shoulda-matchers: when some field is defined as not null on the database, the unique and format matchers raise Errors

Rails 3.1 Ruby 1.9.2 Shoulda-matchers 1.4.1

I have a model Daemon with the following validations:

class Daemon < ActiveRecord::Base validates :name, :presence => true, :format => /\A[\w -.]+\z/ validates :binary, :presence => true etc.

In the migration, it is defined as:

class CreateDaemons < ActiveRecord::Migration def change create_table :daemons do |t| t.string :name, :null => false t.string :binary, :null => false t.string :version, :null => false, :default => ‘unknown’ etc.

when i construct the test: describe Daemon do it { should validate_presence_of(:name) } it { should validate_uniqueness_of(:name) } it { should validate_format_of(:name).with(‘socr-ates on Test DMZ Munich’) } it { should validate_format_of(:name).not_with(‘socr#ates’) }

i get the following errors:

  1. Daemon Failure/Error: it { should validate_uniqueness_of(:name) } ActiveRecord::StatementInvalid: Mysql::Error: Column ‘binary’ cannot be null: INSERT INTO daemons (binary, created_at, installation_id, log_file, name, opt_file, port, report_file, updated_at, version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

    ./spec/models/daemon_spec.rb:7:in `block (2 levels) in <top (required)>’

  2. Daemon Failure/Error: it { should validate_format_of(:name).not_with(‘socr#ates’) } Expected errors to include “is invalid” when name is set to “socr#ates”, got errors: [“binary can’t be blank (nil)”]

    ./spec/models/daemon_spec.rb:9:in `block (2 levels) in <top (required)>’

Now, either the shoulda-matchers only work if i don’t have any not null constraints in the database (then you should add that in the README and in the documentation) or I’m doing something wrong - am I missing something? I also tried to add a before(:each) { FactoryGirl.create(:daemon) } in my spec file, but this also does get me the binary can’t be blank(nil) error in both cases. Thanx in advance for any help/comments

About this issue

  • Original URL
  • State: closed
  • Created 12 years ago
  • Comments: 16

Commits related to this issue

Most upvoted comments

This issue is really a bit of a pain, needed some time to find this page and to create a workaround. I’ve done it like this:

describe Member do
  it { should validate_presence_of(:username).with_message "can't be blank" }
  it { create(:member); should validate_uniqueness_of(:username).case_insensitive }
end

This should be a better way to solve this. A config option to let Shoulda know what factory to use (for example) would be highly appreciated.

An easier thing to do is simply have a record in a fixtures file for this model. Then you won’t have to do anything inside the test to create an instance first, you can just use validates_uniqueness_of as normal.