[rspec-users] Specifying certain tables NOT to be cleared each example?

Scott Taylor mailing_lists at railsnewbie.com
Thu May 22 00:57:43 EDT 2008


On May 21, 2008, at 10:49 PM, Andrew Selder wrote:

> Is it possible to specify that certain tables not be cleared on each  
> example.
>
> I've inherited a project where a good amount of enumerated data is  
> stored in the database (US States, statuses, about 15-20 tables  
> worth. Over all, it's a reasonable decision that leads to solid  
> production code (acts_as_enumerated is good). This data is read-only  
> and relatively static; any changes to these tables are done via  
> migrations.
>
> The problem comes when I'm writing my tests. Obviously all these  
> tables get wiped with each example. Yes, I could specify these as  
> fixtures, but I really don't want to have to specify 15-20 fixtures  
> on every example. Yes, I could mock/stub all the values, except that  
> I use many of these values at class definition time, which means  
> that errors are thrown before I can even mock/stub.
>
> For instance, I have a statement like this.
>
> named_scope :open, :conditions => ["lead_status_id IN (?)", %w{New  
> Incubating Client UAG}.collect{|x| LeadStatus[x].id}]
>
> Which loads the named_scope using the string version of the  
> enumeration for clarity's sake. It works great, except for testing.
>
> Does anybody see anyway around this other than creating a fixture  
> file for each of these tables and loading all the fixtures on each  
> describe block. Not only does this make for ugly code, but I'm sure  
> it takes a good chunk of time to setup and teardown each of the  
> tables each example.
>
> It would be wonderful if there was some option to specify tables  
> that behave like this, that should be loaded at the beginning of the  
> test run, and (optionally) trashed at the end of the run. Or even  
> better, specify that the test script shouldn't touch (build or  
> teardown) these tables at all, and let their migrated state remain.
>

AFAIK, any data that goes into the test database *after* the  
db:test:prepare rake task, but *before* the spec rake task will not  
get wiped out with every test case.

Rails' Fixtures do not get reloaded every test case, but every test  
case will get loaded into a transaction, so any data which is modified  
in those test cases should get rolled back.

I don't see any reason why you couldn't have a factory method which  
would set up that data, make a rake task out of it, and set it the  
dependency for the spec task:

task :spec => :setup_test_data

One problem with this solution is that it precludes any ability to run  
with a single test with script/spec or with autotest.

Another option (although, I'm sure that it will be quite slow) is to  
define a global before(:each) in spec/spec_helper.rb:

Spec::Runner.configure do |config|
   config.use_transactional_fixtures = true
   config.use_instantiated_fixtures  = false

   before(:each) do
    # setup_test_data...
   end
end

Scott



More information about the rspec-users mailing list