jeudi 29 juin 2017

Should we assert specific errors when testing validation in model specs?

There are three common ways to test model validations with RSpec and Rails:

  1. expect(post.errors[:title]).to include("can't be blank")
  2. expect(post.errors[:title].size).to eq(1)
  3. expect(post).to be_valid

IMO, the third option is not good as the record might be invalid due to invalid values in one or more attributes, which may not even include the attribute we intend to test.

So, which approach is best in your opinion, the first or the second?.

A few factors to consider:

Only test what you own

Given that the default error messages for built-in validations are set by the developers of the rails framework (we don't own that code), they may change at any given time and if our validation tests expect specific error messages, they will break.

Regarding custom error messages (for built-in validations and custom validators), although they are under our control, the fact that changing those messages will break our tests makes one wonder if the tests aren't too brittle.

Ensure other validation errors do not influence the test result

  • If both the validation we're testing and another validation fail, post.errors[:title].size will be 2, so both first and second options got this covered.
  • If the validation we expect to fail passes and another validation we were expecting to pass fails (both regarding the attribute under test), then our test will pass when it shouldn't. That's likely the argument in favor of asserting specific error messages when testing validations. Can you think of a way to solve this issue without asserting specific error messages?

Relevant opinions:

  • The rspec-rails developers discuss this subject here.
  • The validation tests included in the book Everyday Rails Testing with RSpec by Aaron Sumner do expect specific error messages.

Thanks in advance.

Aucun commentaire:

Enregistrer un commentaire