Test succeed only when run separately

Hello,

i’ve an initializer which set as constants all the instances retrieved
from the DB, for specific AR models.

Thoose constant are used a bit everywhere in the application.

In my unit test, I run the initializer top preload my “dynamic
constants” in the setup method of the test class. The setup method call
a method in the test_helper class, as follows :

require File.dirname(FILE) + ‘/…/test_helper’

class StatusTest < ActiveSupport::TestCase

setup :preload_constants_from_db

(…)
end

In the test_helper file I got the method preload_constants_from_db,
which require the initializer.

def preload_constants_from_db
require File.expand_path(File.dirname(FILE) +
“/…/config/initializers/constant_cache”)
end

Run separately the test works great :

mac:trunk nico$ ruby test/unit/status_test.rb
Loaded suite test/unit/status_test
Started

Finished in 0.955416 seconds.

4 tests, 5 assertions, 0 failures, 0 errors
mac:trunk nico$ ruby test/unit/status_test.rb
Loaded suite test/unit/status_test
Started

Finished in 0.958518 seconds.

4 tests, 5 assertions, 0 failures, 0 errors

But run whith rake everything fails :

rake test:units

=> BOUM

Any idea how to proceed ??

PS: Sorry for the approximative english…

On Jun 14, 9:53 pm, nico Itkin [email protected]
wrote:

But run whith rake everything fails :

rake test:units

=> BOUM

How does it fail ? What is in constant_cache.rb ?

Fred

Frederick C. wrote:

On Jun 14, 9:53�pm, nico Itkin [email protected]
wrote:

But run whith rake everything fails :

rake test:units

=> BOUM

How does it fail ? What is in constant_cache.rb ?

Fred

The constant settings :

module ConstantCache
module ClassMethods
def cache_constants(field=nil)
find(:all).each do |instance|
if field and !instance.send(field).blank?
const = instance.send(field).gsub(/\s+/, ‘').upcase
const_set(const, instance) unless const_defined?(const)
elsif field.nil?
const = instance.name.gsub(/\s+/, '
’).upcase
const_set(const, instance) unless const_defined?(const)
end
end
end
def const_get(arg)
arg.is_a?(Symbol) ? super(arg.to_s.upcase) : super(arg)
end
end
end

ActiveRecord::Base.send(:extend, ConstantCache::ClassMethods)

For exemple in status_action.rb

class StatusAction < Action

cache_constants :name

has_many :statuses, :foreign_key=>‘action_id’

end

… all the instance of type StatusAction become constants called
StatusAction::THE_RECORD_NAME_FIELD

well the strangest is that is contant_cache seems not to be correctly
run from rake…

Frederick C. wrote:

On Jun 14, 11:23�pm, nico Itkin [email protected]
wrote:

Frederick C. wrote:

… all the instance of type StatusAction become constants called
StatusAction::THE_RECORD_NAME_FIELD

well the strangest is that is contant_cache seems not to be correctly
run from rake…

So what exactly happens when you run rake ?

Fred

When I run ruby unit/status_test.rb : everything is fine, constants are
all present

When I run rake test:units : no constant is set, as if constant_cache
hasn’t been run

… so my trouble

Thanks, Itkin

On Jun 15, 8:23 am, nico Itkin [email protected]
wrote:

So what exactly happens when you run rake ?

Fred

When I run ruby unit/status_test.rb : everything is fine, constants are
all present

When I run rake test:units : no constant is set, as if constant_cache
hasn’t been run

Did you stick a breakpoint in constant_cache ? I rather suspect that
it is running but that the particular sequence of actions that takes
place means that it happens before fixtures have been loaded.
When you run rake the test database is recreated from scratch and so
starts of empty (and then fixtures are loaded).
When you run a single test file then the test database isn’t recreated
and so the fixtures are already there.

Your setup method probably runs after fixtures have been loaded, but
all it does is call require and that file was already required earlier
on when rails loaded your initializers so those requires may well be
no-ops.

Fred

Frederick C. wrote:

On Jun 15, 8:23�am, nico Itkin [email protected]
wrote:

So what exactly happens �when you run rake ?

Fred

When I run ruby unit/status_test.rb �: everything is fine, constants are
all present

When I run rake test:units �: no constant is set, as if constant_cache
hasn’t been run

Did you stick a breakpoint in constant_cache ? I rather suspect that
it is running but that the particular sequence of actions that takes
place means that it happens before fixtures have been loaded.
When you run rake the test database is recreated from scratch and so
starts of empty (and then fixtures are loaded).
When you run a single test file then the test database isn’t recreated
and so the fixtures are already there.

Your setup method probably runs after fixtures have been loaded, but
all it does is call require and that file was already required earlier
on when rails loaded your initializers so those requires may well be
no-ops.

Fred

Thanks Fred for your help,

I guess you’re right, do you know a nice way to force constant_cache to
be run before each test ?

Otherwise I think i’ll try to prevent rake to prepare db before running
tests, but i’m not sure this is an optimal solution to my pb.

Itkin

On Jun 14, 11:23 pm, nico Itkin [email protected]
wrote:

Frederick C. wrote:

… all the instance of type StatusAction become constants called
StatusAction::THE_RECORD_NAME_FIELD

well the strangest is that is contant_cache seems not to be correctly
run from rake…

So what exactly happens when you run rake ?

Fred

On Jun 15, 9:05 am, nico Itkin [email protected]
wrote:

Frederick C. wrote:

Thanks Fred for your help,

I guess you’re right, do you know a nice way to force constant_cache to
be run before each test ?

Otherwise I think i’ll try to prevent rake to prepare db before running
tests, but i’m not sure this is an optimal solution to my pb.

it’s not actually the running the tests that does it, it’s when the
model is loaded (since that is when cache_constants is called). I’m
not sure you current setup method does anything since (best case
scenario) it causes a file to be loaded that adds some methods to
activerecord classes (but doesn’t actually call them). You could try
calling Status.cache_constants from your setup method.

Fred

Frederick C. wrote:

On Jun 15, 9:05�am, nico Itkin [email protected]
wrote:

Frederick C. wrote:

Thanks Fred for your help,

I guess you’re right, do you know a nice way to force constant_cache to
be run before each test ?

Otherwise I think i’ll try to prevent rake to prepare db before running
tests, but i’m not sure this is an optimal solution to my pb.

it’s not actually the running the tests that does it, it’s when the
model is loaded (since that is when cache_constants is called). I’m
not sure you current setup method does anything since (best case
scenario) it causes a file to be loaded that adds some methods to
activerecord classes (but doesn’t actually call them). You could try
calling Status.cache_constants from your setup method.

Fred

it works !!!

thanks a lot Fred ! Itkin

2009/6/15 Frederick C. [email protected]:

be run before each test ?

Otherwise I think i’ll try to prevent rake to prepare db before running
tests, but i’m not sure this is an optimal solution to my pb.

I had a very similar problem recently and solved it by changing my
constants to class variables of the appropriate models, then in the
accessor function for each variable, tested for nil and read from db
if necessary. In fact if nil I read the whole set of variables for
that model. I have decided that using class variables is actually
nicer as it locates the ‘constants’ with the appropriate model.

Colin