-
-
Notifications
You must be signed in to change notification settings - Fork 394
Block matchers (e.g. #change
) only support passing procs to expect.
#1106
Comments
This has sort of come up before, and a gem was created to expand the inline syntax to add something similar. https://github.com/d-unseductable/rspec-has in this case I feel you could happily solve the problem in a similar fashion by creating an alias for |
I am wondering if it is a good idea too. I find it a little less explicit, but maybe because I have too many habits. 🤷♂️ I would prefer the approach of |
Would you consider a nested expectation as an option @lukeredpath ?
Another option would be to use explicit block syntax:
Related: some thoughts on implicit block syntax's complications. |
@lukeredpath what are your thoughts on this? |
@lukeredpath What do you think of alternative ways to achieve the same goal? |
There are multiple mechanisms in RSpec and Ruby that would allow to write a concise spec like this: describe "DELETE /widget/:id" do
subject(:request) { make_deferred_request(:delete, "/widget/#{widget.id}") }
it { expect { request }.to change(Widget, :count).by(-1) }
it { expect { request }.to change { response.status }.to(:found) }
end or for those who don't blindly follow the one literal expectation per example rule: it do
expect { request }
.to change(Widget, :count).by(-1)
.and change { response.status }.to(:found)
end All at the same time without blurring the line between block and value expectations. @lukeredpath Please feel free to open if you have a clear vision on how to proceed with this issue. |
Subject of the issue
Certain matchers, like
#change
, require that you pass aproc
to#expect
- this makes sense, it needs to be able to defer invoking the operation inside the block in order to test the before and after values.However, this hard requirement for a
Proc
denies us the opportunity to create higher-level abstractions. For instance, wrapping a request in a Rails request test, I'm quite keen of using the pattern of defining a spec's subject as the request inside a proc that can be passed toexpect
in order to succinctly test the request's side effects, for example:The downside to this pattern is that if I want to test something after the request is made, I need to explicitly call it:
It would be nice to be able to wrap this pattern up in a callable object which encapsulates both the request and the response and when combined with something like
rspec-its
can lead to some nicely succinct specs:Unfortunately this fails with the error:
expected
Widget.countnot to have changed, but was not given a block
Expected behavior
It would be better if matchers that expected a
proc
argument toexpect
in fact accepted any object that responded to#call
- this would allow the following abstraction to work. This would be a backwards-compatible API becauseProc
already responds to#call
.I'm happy to look at submitting a PR for this change but wanted to get some feedback first.
The text was updated successfully, but these errors were encountered: