Plugin test fixtures

Just spent a good bit of time trying to figure out why I couldn't get fixtures to work in a plugin test. I was including ActiveRecord::TestFixtures into ActiveSupport::TestCase and trying to get fixtures to automatically reload for every test like regular Rails tests.

The problem was in the first line of ActiveRecord::TestFixtures.setup_fixtures:
return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?

This causes setup_fixtures to silently return without doing anything if you call ActiveRecord::Base.establish_connection directly without setting ActiveRecord::Base.configurations. The method doesn't appear to actually use the configurations.

Is there some reason for this behavior? It appears like it should be removed to me, but if it is there for a reason, maybe it can be documented that populating configurations is a prerequisite to using fixtures in plugins.

I am using 2.3.5 but it appears to still be the case in edge.

Jack

Just spent a good bit of time trying to figure out why I couldn't get
fixtures to work in a plugin test. I was including
ActiveRecord::TestFixtures into ActiveSupport::TestCase and trying to get
fixtures to automatically reload for every test like regular Rails tests.

ActiveSupport::TestCase *does* have fixtures support, I'm not sure
what you're trying to get done here?

The problem was in the first line of
ActiveRecord::TestFixtures.setup_fixtures:
return unless defined?(ActiveRecord) &&
!ActiveRecord::Base.configurations.blank?

This causes setup_fixtures to silently return without doing anything if you
call ActiveRecord::Base.establish_connection directly without setting
ActiveRecord::Base.configurations. The method doesn't appear to actually use
the configurations.

Is there some reason for this behavior? It appears like it should be removed
to me, but if it is there for a reason, maybe it can be documented that
populating configurations is a prerequisite to using fixtures in plugins.

This is to avoid breaking people trying to use ActiveSupport::TestCase
subclasses without active record configured in their application, we
could change that logic to support your case where you've connected
manually, but due to how things are laid out there'll still need to be
some short-circuiting behaviour to avoid a bunch of misleading errors.

Just spent a good bit of time trying to figure out why I couldn't get
fixtures to work in a plugin test. I was including
ActiveRecord::TestFixtures into ActiveSupport::TestCase and trying to get
fixtures to automatically reload for every test like regular Rails tests.
     

ActiveSupport::TestCase *does* have fixtures support, I'm not sure
what you're trying to get done here?

Yes it does. But it was silently failing.

The problem was in the first line of
ActiveRecord::TestFixtures.setup_fixtures:
return unless defined?(ActiveRecord)&&
!ActiveRecord::Base.configurations.blank?

This causes setup_fixtures to silently return without doing anything if you
call ActiveRecord::Base.establish_connection directly without setting
ActiveRecord::Base.configurations. The method doesn't appear to actually use
the configurations.

Is there some reason for this behavior? It appears like it should be removed
to me, but if it is there for a reason, maybe it can be documented that
populating configurations is a prerequisite to using fixtures in plugins.
     

This is to avoid breaking people trying to use ActiveSupport::TestCase
subclasses without active record configured in their application, we
could change that logic to support your case where you've connected
manually, but due to how things are laid out there'll still need to be
some short-circuiting behaviour to avoid a bunch of misleading errors.
   

In a plugin we have to explicitly include ActiveRecord::TestFixtures to enable fixtures in ActiveSupport::TestCase. So my thinking is it should loudly fail instead of silently fail if it doesn't think ActiveRecord is setup. Now if I understand you correctly, you are saying that that would cause problems in Rails applications that aren't using ActiveRecord, because the main Rails test framework automatically includes ActiveRecord::TestFixtures into ActiveSupport::TestCase. It's probably not be worth changing Rails to only include ActiveRecord::TestFixtures into ActiveSupport::TestCase if ActiveRecord is in use, but it would be helpful to document somewhere the dependency between ActiveRecord::Base.configurations and fixtures.

Jack

In a plugin we have to explicitly include ActiveRecord::TestFixtures to
enable fixtures in ActiveSupport::TestCase. So my thinking is it should
loudly fail instead of silently fail if it doesn't think ActiveRecord is
setup. Now if I understand you correctly, you are saying that that would
cause problems in Rails applications that aren't using ActiveRecord, because
the main Rails test framework automatically includes
ActiveRecord::TestFixtures into ActiveSupport::TestCase. It's probably not
be worth changing Rails to only include ActiveRecord::TestFixtures into
ActiveSupport::TestCase if ActiveRecord is in use, but it would be helpful
to document somewhere the dependency between
ActiveRecord::Base.configurations and fixtures.

You could also change the logic to be something along the lines of:

defined?(ActiveRecord) && (!ActiveRecord::Base.configurations.blank?

already_connected_to_a_database)

That would probably serve your case without breaking everyone else's.

Alternatively perhaps logging (with debug level) a warning "fixtures
not initialized because database not configured". However that could
get spammy