What is the correct format for using shoulda-matchers and RSpec's new expect syntax?
-
Sorry I meant shoulda – trev9065 Sep 08 '13 at 12:42
-
Regarding the vote-to-close based on this being primarily opinion based, I would argue that this particular instance of asking if something is a "good idea" is an exception because there is a fact-based explanation that the concern is a non-issue. – Peter Alfvin Sep 08 '13 at 13:52
-
edited the quesrion detail to make it be appropriate for SO. – Michael Durrant Sep 08 '13 at 16:21
2 Answers
While one could certainly use the shoulda-matchers with the new expect syntax as follows:
it 'should validate presence of :email' do
expect(subject).to validate_presence_of :email
end
or the more concise but less readable:
it { expect(subject).to validate_presence_of :email }
the one-liner should
format these matchers are typically used with is explicitly supported in 2.14 even when config.syntax == :expect
. When should
is being used with an implicit subject as in:
describe User
it { should validate_presence_of :email }
end
it does not rely on the monkey patching of Kernel
that should
otherwise depends on.
This is covered in https://github.com/rspec/rspec-expectations/blob/master/Should.md. In fact, that documentation even uses the above shoulda
matcher example to illustrate this exception.
See also Using implicit `subject` with `expect` in RSpec-2.11, which discusses a configuration option which lets you use as an alternative to it
.
expect_it { to validate_presence_of :email }
Update: As of RSpec 3.0 (beta2), you will also be able to use:
it { is_expected.to validate_presence_of :email }

- 1
- 1

- 28,599
- 8
- 68
- 106
-
The first block would also be surrounded by the `desribe User`, right? As it it looks like a omparison of 3 lines to 3 different lines, but isn't quite that. If so might want to add that for clarity in first code block. – Michael Durrant Sep 08 '13 at 14:54
-
@MichaelDurrant Yes, it would. Agreed. Thanks for pointing this out. Answer updated. – Peter Alfvin Sep 08 '13 at 15:05
-
Anyone have any idea what the downvote is for? Is it related to the close votes for this being "primarily opinion based"? – Peter Alfvin Sep 08 '13 at 15:40
-
It's too bad that you need the it block. I always liked shoulda matches because of their concise syntax. – trev9065 Sep 10 '13 at 11:12
-
Actually, you _don't_ need the block. That was what I intended as the essence of my answer. The one-liner `should` form is completely acceptable and fully accepted/supported by the latest convention. But you did give me an idea. What if RSpec introduced `expect_it` as an alias for `expect(subject)`? – Peter Alfvin Sep 10 '13 at 14:07
I'll suplement the answer of @peter-alfvin. In case you test the model and its migration themselves with shoulda-matchers
you can't use :expect
outside of it
block, so can't write:
RSpec.describe ModelName, type: :model do
expect(subject).to belong_to(:user)
end
And you will get the expection:
`expect` is not available on an example group (e.g. a `describe` or `context` block).
but correct version is:
RSpec.describe ModelName, type: :model do
it { expect(subject).to belong_to(:user) }
end

- 16,187
- 5
- 56
- 69