27

I'm testing my ActiveRecord models with Rspec. I've just added a custom error message to one of my validations, like this:

validates :accepted_terms_at, :presence => {:message => 'You must accept the Terms and Conditions to use this site.'}

Now the following test fails:

it { should validate_presence_of(:accepted_terms_at) }

... with the error Expected errors to include "can't be blank" when accepted_terms_at is set to nil.

So the test fails because it's looking through the validation error messages and expects to find the default one.

How can I tell Rspec what the new validation message should be?

What I've tried

1) Message as an argument:

it {should validate_presence_of(:accepted_terms_at, :message => 'your message')}

This gives the error wrong number of arguments (2 for 1)

2) Message as a chained method call

it {should validate_presence_of(:accepted_terms_at).with('your message')}

This throws an error because there is no with method.

tal
  • 3,423
  • 1
  • 25
  • 21
Nathan Long
  • 122,748
  • 97
  • 336
  • 451
  • 1
    The first thing I'd try is `it { should validate_presence_of(:accepted_terms_at, :message => 'your message') }` but I have no idea if that'll actually work, and don't have a setup to test right now. – Emily Dec 08 '11 at 15:25
  • @Emily - I tried that; it give me "wrong number of arguments (2 for 1)" – Nathan Long Dec 08 '11 at 15:27
  • it's more a shoulda question by the way – tal Jan 18 '12 at 10:49

3 Answers3

47

It's included and standard in shoulda :

it { should validate_presence_of(:name).
            with_message(/is not optional/) }

http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/Shoulda/Matchers/ActiveModel:validate_presence_of

tal
  • 3,423
  • 1
  • 25
  • 21
0

The Verbose Way

This test works, it's just not as concise as I'd like.

it "should validate the presence of accepted_terms_at" do
  @user.accepted_terms_at = nil
  @user.valid?
  message = "You must accept the Terms and Conditions to use this site."
  expect {@user.errors.messages.include?(message)}.to be_true
end
Nathan Long
  • 122,748
  • 97
  • 336
  • 451
0

You have two options.

First, you could live with just asserting that the model is not valid when the terms have not been accepted.

Second, stop testing specific error messages, by defining your custom error message:

https://stackoverflow.com/a/7108254/162793

Then you can look for the symbol for the error message, rather than for the text of the error message.

Community
  • 1
  • 1
sheldonh
  • 2,684
  • 24
  • 31