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