Shoulda-Matchers and database-level not-null constraints

The shoulda-matchers gem makes it easy to test basic functionality of your app (mostly the model and controller layers it seems), without writing a whole lot of custom code.

However, when using shoulda-matchers, if you have a database-level NOT NULL constraint on your model, then you may have to adjust how you write the tests in order for them to function properly.

The following test of the uniqueness validation on unique_column won’t work if you have a NOT NULL constraint on the required_column at the database level:

describe SomeModel do
  it { should validate_presence_of(:required_column) }
  it { should validate_uniqueness_of(:unique_column) }
end

Instead, you first create a valid record (here this is done using a FactoryGirl factory), and then you run the test on that pre-existing record, as such:

  describe SomeModel do
    it { should validate_presence_of(:required_column) }

    let(:some_model) { create(:some_model) }
    subject { some_model }
    
    it { should validate_uniqueness_of(:unique_column) }
  end

This is the explanation, from the rdoc:

– (Object) validate_uniqueness_of(attr)

Ensures that the model is invalid if the given attribute is not unique. It uses the first existing record or creates a new one if no record exists in the database. It simply uses `:validate => false` to get around validations, so it will probably fail if there are `NOT NULL` constraints. In that case, you must create a record before calling `validate_uniqueness_of`.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s