views:

955

answers:

2

I'm currently in the process of beginning a migration from fixtures to factories and running into some test database challenges.

When I run my entire test suite the database is cleaned out and the new factory-generated data reloaded. However, when I run individual unit tests the database does not clean out the old values.

I could run rake db:test:prepare before each individual test, but that would slow down my development.

Here are my test settings:

  self.use_transactional_fixtures = false
  self.use_instantiated_fixtures  = true

For instance:

require File.dirname(__FILE__) + '/../test_helper'
class LocationTest < ActiveSupport::TestCase
  test "should require name to save" do
    location = Factory.create(:location)
  end
end

will run once successfully but fail on subsequent runs of the test file. This never happened previously because the test fixtures would load on each run.

I have added factory sequencing, but that only sequences attributes during each run:

  Factory.define :location do |l|
    l.sequence(:name) {|n| "place#{n}"}
    l.street  '123 N Pitt Street'
    l.state_id 4
    l.city 'San Francisco'
    l.location_type_id LocationType::COMMON
    l.shipper_id 1
    l.zip 23658
  end

results in:

trunk>ruby test\unit\location_test.rb
Loaded suite test/unit/location_test
Started
.
Finished in 0.162 seconds.

1 tests, 0 assertions, 0 failures, 0 errors

>ruby test\unit\location_test.rb
Loaded suite test/unit/location_test
Started
E
Finished in 0.134 seconds.

  1) Error:
test_should_require_name_to_save(LocationTest):
ActiveRecord::RecordInvalid: Validation failed: Name has already been taken
    c:/ruby/lib/ruby/gems/1.8/gems/thoughtbot-factory_girl-1.2.1/lib/factory_girl/proxy/create.rb:5:in `result'
    c:/ruby/lib/ruby/gems/1.8/gems/thoughtbot-factory_girl-1.2.1/lib/factory_girl/factory.rb:293:in `run'
    c:/ruby/lib/ruby/gems/1.8/gems/thoughtbot-factory_girl-1.2.1/lib/factory_girl/factory.rb:237:in `create'
    test/unit/location_test.rb:18:in `test_should_require_name_to_save'

1 tests, 0 assertions, 0 failures, 1 errors
A: 

You could override the setup method in your unit test so that it deletes the data you want cleaned out.

John Topley
A: 

First check your test settings to make certain that they are what you want, although I suspect you may have a reason to disallow the standard practice of running a test in a transaction (which is rolled back upon exit).

The other options is (1) Manually use transactions for tests like the one above (where there is not already a transaction), plus (2) Add a teardown method to manually clean out the relevant tables.

Kathy Van Stone
Add:self.use_transactional_fixtures = trueto this class and it works! Thank you.Yes, there are reasons why I cannot change it for the whole environment. I didn't even think to change it for just this one test...doh!Thanks again.
Kevin Dewalt