-
-
Notifications
You must be signed in to change notification settings - Fork 397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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: