Forum: RSpec set_fixture_class works on individual test, but test suite fails

Posted by Stephen Kessler (Guest)
on 2011-11-14 21:49
(Received via mailing list)
Hi all,

I have a bug in my code that I have been unable to track down that
deals with the set_fixture_class statement.  Basically,
set_fixture_class (and my tests) are working fine when I test one
controller in isolation, but they are failing when I run all my
controller specs together.

My project use both a local database and Amazon Rds, and the tables on
Amazon are namespaced with Rds::TableName.

My controller spec looks something like:

describe MyFirstController do
  set_fixture_class :users => Rds::User

  describe 'my test' do
    it 'should do something' do
      joe = users(:joe)
    end
  end
end

This works fine when running just this controller's spec.  But when I
run all the controller specs, the error I get is:

Failure/Error: joe = users(:joe)
FixtureClassNotFound:
       No class attached to find.

I have isolated the problem to the interaction between two controller
specs, MyFirstController (which contains set_fixture_class) and
MySecondController (which does not contain set_fixture_class).  When
the tests for MyFirstController are run before the tests for
MySecondController, everything works fine.  But when the order is
reversed, I get the above errors.

Any ideas on what I might be able to do to fix this (besides requiring
MyFirstController to run first)?
Posted by David Chelimsky (Guest)
on 2011-11-15 06:09
(Received via mailing list)
On Nov 8, 2011, at 10:52 AM, Stephen Kessler wrote:

>
> My controller spec looks something like:
>
> describe MyFirstController do
>  set_fixture_class :users => Rds::User

set_fixture_class is defined in rails: 
https://github.com/rails/rails/blob/master/activer...

It's a class method that interacts with a class_attribute defined in the 
same file: 
https://github.com/rails/rails/blob/master/activer...

This means that once it's set, it's set, which explains the behavior 
you're seeing.

You can get around this by storing the original setting and restoring it 
in an after block:

before do
  @orig = self.class.fixture_class_names[:users]
  self.class.fixture_class_names[:users] = Rds::User
end

after do
  self.class.fixture_class_names[:users] = Rds::User
end

This is very invasive as it interacts directly with variables instead of 
APIs, so it might easily break in a future version of rails, but I'm not 
sure what better option you have. It's not really designed to be used 
how you're using it.

HTH,
David
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.