Using Rails 3.1.1 by the way. To reproduce this create a new Rails project. Create a new model within this project under the name Example. Create a migration for this model that looks as follows...
class CreateExamples < ActiveRecord::Migration
def change
create_table :examples do |t|
t.integer :status, :null => false
t.timestamps
end
end
end
Have the example model code look as follows...
class Example < ActiveRecord::Base
VALID_VALUES = [0, 1, 2, 3]
validates :status, :presence => true, :inclusion => {:in => VALID_VALUES}
end
Now edit the unit test for this model and add the following code to it...
require 'test_helper'
class ExampleTest < ActiveSupport::TestCase
test "whats going on here" do
example = Example.new(:status => "string")
assert !example.save
end
end
Edit the fixtures file so that it doesn't create any records and then run the unit test with a command such as bundle exec rake test:units. This test should pass as "string" is not a valid status so the example object should return false from the call to save. This is not happening. If you take the 0 out of the VALID_VALUES array then this works. Anyone any idea why this might be the case?
"string" is casted as an integer (as your status column is an integer) before validation
"string".to_i # => 0
You can avoid this by using the numericality validator :
validates :status, :presence => true, :numericality => { :only_integer => true }, :inclusion => {:in => VALID_VALUES}
BTW, you can use #valid? or #invalid? method instead of #save in your test