[rspec-users] Insufficient database clean-up between specs

Matt Wynne matt at mattwynne.net
Tue Mar 16 06:10:35 EDT 2010


On 15 Mar 2010, at 12:34, David Chelimsky wrote:

> On Mon, Mar 15, 2010 at 7:24 AM, jollyroger
> <timo.roessner at googlemail.com> wrote:
>> Hey guys,
>>
>> unfortunately I've got one more issue with rspec right now.
>>
>> It seems like rspec isnt properly cleaning up the database after each
>> spec.
>>
>> I have the following spec:
>>
>> ###################################################################
>> describe ProfilesController do
>>  describe "GET 'index'" do
>>    it 'should render active profiles' do
>>      active_user = Factory(:user, :active => 1)
>>      active_user.profile = Factory.build(:profile)
>>      inactive_user = Factory(:user, :active => 0)
>>      inactive_user.profile = Factory.build(:profile)
>>      get 'index'
>>      assigns[:profiles].should == [active_user.profile]
>>    end
>>  end
>>  # ......
>> end
>> ###################################################################
>>
>> This spec fails with:
>>
>> ###################################################################
>> 'ProfilesController GET 'index' should render active profiles' FAILED
>> expected: [#<Profile id: 83, user_id: 80, real_name: "Wendy Moore",
>> country: "Yemen, Rep.", icon_file_name: nil, icon_content_type: nil,
>> icon_file_size: nil, icon_updated_at: nil, description: "I've gotten
>> burned over Cheryl Tiegs and blown up f...", personal_website_url:
>> "www.google.com", social_network_of_choice: nil, twitter_name:
>> "Sarah", created_at: "2010-03-15 11:41:56", updated_at: "2010-03-15
>> 11:41:56">],
>>     got: [#<Profile id: 83, user_id: 80, real_name: "Wendy Moore",
>> country: "Yemen, Rep.", icon_file_name: nil, icon_content_type: nil,
>> icon_file_size: nil, icon_updated_at: nil, description: "I've gotten
>> burned over Cheryl Tiegs and blown up f...", personal_website_url:
>> "www.google.com", social_network_of_choice: nil, twitter_name:
>> "Sarah", created_at: "2010-03-15 11:41:56", updated_at: "2010-03-15
>> 11:41:56">, #<Profile id: 37, user_id: 37, real_name: nil, country:
>> nil, icon_file_name: nil, icon_content_type: nil, icon_file_size:  
>> nil,
>> icon_updated_at: nil, description: nil, personal_website_url: nil,
>> social_network_of_choice: nil, twitter_name: nil, created_at:
>> "2010-03-15 11:21:15", updated_at: "2010-03-15 11:21:15">, #<Profile
>> id: 40, user_id: 40, real_name: nil, country: nil, icon_file_name:
>> nil, icon_content_type: nil, icon_file_size: nil, icon_updated_at:
>> nil, description: nil, personal_website_url: nil,
>> social_network_of_choice: nil, twitter_name: nil, created_at:
>> "2010-03-15 11:21:15", updated_at: "2010-03-15 11:21:15">, #<Profile
>> id: 52, user_id: 52, real_name: nil, country: nil, icon_file_name:
>> nil, icon_content_type: nil, icon_file_size: nil, icon_updated_at:
>> nil, description: nil, personal_website_url: nil,
>> social_network_of_choice: nil, twitter_name: nil, created_at:
>> "2010-03-15 11:21:15", updated_at: "2010-03-15 11:21:15">] (using ==)
>> ###################################################################
>>
>> As you can see, the problem is that there are more profiles than
>> actually expected.
>>
>> Running this exact spec alone is ok:
>>
>> ###################################################################
>> spec spec/controllers/profiles_controller_spec.rb -l 17
>> .
>>
>> Finished in 7.743924 seconds
>>
>> 1 example, 0 failures
>> ###################################################################
>>
>> The same goes for the whole spec-file itself:
>>
>> ###################################################################
>> spec spec/controllers/profiles_controller_spec.rb
>> ............
>>
>> Finished in 6.108002 seconds
>>
>> 12 examples, 0 failures
>> ###################################################################
>>
>> A quick debugging via:
>>
>> ###################################################################
>>    it 'should render active profiles' do
>>      custom_log("Profile-count before: #{Profile.count.to_s}")
>>      # ........ see code from before
>>      get 'index'
>>      custom_log("Profile-count after: #{Profile.count.to_s}")
>>      assigns[:profiles].should == [active_user.profile]
>>    end
>> ###################################################################
>>
>> shows:
>>
>> ###################################################################
>> Profile-count before: 3
>> Profile-count after: 5
>> ###################################################################
>>
>> Apparently the problem is, that there are still previously created
>> profiles around.
>>
>> As far as I've understood rspec, shouldn't the database be properly
>> cleaned up after each spec?
>> In other words, shouldn't there be zero profiles before running the
>> spec from above?
>
> rspec-rails hooks into rails' transaction management, rolling back
> transactions after every example. It does not guarantee that your
> database is empty - just that it is in the same state after each
> example that it was in before. Now there are a couple of caveats here:
>
> 1 - you have to have "config.use_transactional_fixtures = true" in
> spec/spec_helper.rb
>
> This is rails' nomenclature and really means "run each example in a  
> transaction"
>
> 2 - if you use before(:all) anywhere in your suite, that code is _not_
> run in a transaction and it is up to you to destroy any data you
> create.

3. If you make any dirty little direct SQL calls (using  
ActiveRecord::Base.connection.execute) while the example runs, that  
will commit the transaction so it's won't be rolled back.


cheers,
Matt

http://mattwynne.net
+447974 430184



More information about the rspec-users mailing list