shoulda-matchers RSpec expect syntax
Asked Answered
E

2

27

What is the correct format for using shoulda-matchers and RSpec's new expect syntax?

Erect answered 8/9, 2013 at 3:35 Comment(3)
Sorry I meant shouldaErect
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.Irriguous
edited the quesrion detail to make it be appropriate for SO.Kob
I
59

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 }
Irriguous answered 8/9, 2013 at 13:48 Comment(5)
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.Kob
@MichaelDurrant Yes, it would. Agreed. Thanks for pointing this out. Answer updated.Irriguous
Anyone have any idea what the downvote is for? Is it related to the close votes for this being "primarily opinion based"?Irriguous
It's too bad that you need the it block. I always liked shoulda matches because of their concise syntax.Erect
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)?Irriguous
C
0

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
Committal answered 5/10, 2015 at 17:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.