How can I use `should validate_presence_of` with a custom error message?
Asked Answered
D

3

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.

Deltoro answered 8/12, 2011 at 15:14 Comment(3)
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.Amargo
@Amargo - I tried that; it give me "wrong number of arguments (2 for 1)"Deltoro
it's more a shoulda question by the wayBlindheim
B
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

Blindheim answered 18/1, 2012 at 10:47 Comment(1)
Awesome! Thanks for finding that.Deltoro
D
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
Deltoro answered 8/12, 2011 at 15:30 Comment(0)
E
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://mcmap.net/q/107517/-fully-custom-validation-error-message-with-rails

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

Extracurricular answered 8/12, 2011 at 17:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.