Chaining expectations in RSpec
I had troubles chaining several opposite assertions in RSpec. In Minitest you can do:
assert_no_differense "MyModel.count" do
assert_difference "MyModel.visible.count", -1 do
delete my_model_path(my_model)
end
end
Whereas in RSpec something like this
expect {
delete my_model_path(my_model)
}.not_to change { MyModel.count }.and change {
MyModel.visible.count }.by(-1)
causes an error:
NotImplementedError:`expect(...).not_to matcher.and matcher` is not supported,
since it creates a bit of an ambiguity.
Instead, define negated versions of whatever matchers you wish to negate with
`RSpec::Matchers.define_negated_matcher` and use `expect(...).to matcher.and matcher`.
So I defined my custom negated matcher at the top of the file:
RSpec::Matchers.define_negated_matcher :not_change, :change
where not_change
- name of a new matcher and change
- the original matcher that should be negated.
Then modified the assertion as follows:
expect {
delete my_model_path(my_model)
}.to not_change { MyModel.count }.and change {
MyModel.visible.count }.by(-1)
Worked like a charm.