Rails - validate inclusion fails on rake test:integration

I see different results when running 'rake test' and when running 'rake test:integration'.

When running all tests with 'rake test' all tests pass. When running 'rake test:integration' I have a failed test because my model fails to validate inclusion of an attribute before saving.

My model looks something like:

  class Order < ActiveRecord::Base     belongs_to :payment_type     validates :payment_type, :inclusion => PaymentType.all     ...   end

PaymentType is a lookup table, which I have a fixture for.

When debugging the save method in the Order model I see that it fails the inclusion validation (again, only when running just the integration tests), but

  PaymentType.all.include?(payment_type)

evaluates to 'true'.

Any ideas why it fails when running only integration tests?

I see different results when running 'rake test' and when running 'rake test:integration'.

When running all tests with 'rake test' all tests pass. When running 'rake test:integration' I have a failed test because my model fails to validate inclusion of an attribute before saving.

My model looks something like:

class Order < ActiveRecord::Base    belongs_to :payment_type    validates :payment_type, :inclusion => PaymentType.all    ... end

PaymentType is a lookup table, which I have a fixture for.

When debugging the save method in the Order model I see that it fails the inclusion validation (again, only when running just the integration tests), but

PaymentType.all.include?(payment_type)

evaluates to 'true'.

Any ideas why it fails when running only integration tests?

The call to validates (and thus the evaluation of its argument) happens when your order class is loaded. If this happens before your fixtures are loaded then you'll effectively be doing validates :blah, :inclusion =>

Why running rake test versus rake test:integration matters I don't know - perhaps one has extra dependencies that force fixtures to be loaded earlier or later, but either way I've generally tried to avoid this sort of thing. I'm not sure what your current code gets you over just validating the presence of the payment_type

Fred

Frederick Cheung wrote in post #1035416:

   belongs_to :payment_type

PaymentType.all.include?(payment_type)

evaluates to 'true'.

Any ideas why it fails when running only integration tests?

The call to validates (and thus the evaluation of its argument) happens when your order class is loaded. If this happens before your fixtures are loaded then you'll effectively be doing validates :blah, :inclusion =>

Why running rake test versus rake test:integration matters I don't know - perhaps one has extra dependencies that force fixtures to be loaded earlier or later, but either way I've generally tried to avoid this sort of thing. I'm not sure what your current code gets you over just validating the presence of the payment_type

Fred

Thanks Fred. You're right, when debugging the validate inclusion code, I see that the PaymentType.all returns .

I guess, like you said, that when the Order class is loaded and the inclusion is evaluated the PaymentType fixture wasn't loaded yet.

But that brings up another question, isn't that a bug in rake/rails?

Why aren't the fixtures being loaded prior to being used? Why isn't PaymentType loaded before Order is?

Ori

I don't think any specific guarantees are made about when fixtures are loaded apart from the fact that by the time your test runs they are loaded or about the order in which any of this stuff happens.

Fred

Frederick Cheung wrote in post #1035592:

PaymentType loaded before Order is?

I don't think any specific guarantees are made about when fixtures are loaded apart from the fact that by the time your test runs they are loaded or about the order in which any of this stuff happens.

Fred

I understand that fixtures are guaranteed to be fully loaded only when my test runs, the problem is, like you said, that the model class validation is evaluated before that.

Another approach I tried was not to use fixtures at all, since payment types are actually seed data and not sample data. That approach failed as well for the same reason that the model validation is called from the engine initialization which is done before the seed data gets populated.

The question remains, how can I use validates inclusion on a lookup table and not fail the test (when running only integration tests).

Ori

why validate the inclusion at all ? I'd validate the presence of the foo_id column and use a foreign key constraint to ensure that it can't contain junk.

Fred

Frederick Cheung wrote in post #1035726: