Set_fixture_class works on individual test, but test suite fails

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)?

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/activerecord/lib/active_record/fixtures.rb#L745

It’s a class method that interacts with a class_attribute defined in the
same file:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/fixtures.rb#L727

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs