RSpec: Expect to change multiple
BroiSatse's answer is the best, but if you are using RSpec 2 (or have more complex matchers like .should_not
), this method also works:
lambda {
lambda {
lambda {
lambda {
click_button 'Save'
@user.reload
}.should change {@user.name}.from('donald').to('gustav')
}.should change {@user.updated_at}.by(4)
}.should change {@user.great_field}.by_at_least(23)
}.should change {@user.encrypted_password}
If you want to test that multiple records were not changed, you can invert a matcher using RSpec::Matchers.define_negated_matcher
. So, add
RSpec::Matchers.define_negated_matcher :not_change, :change
to the top of your file (or to your rails_helper.rb
) and then you can chain using and
:
expect{described_class.reorder}.to not_change{ruleset.reload.position}.
and not_change{simple_ruleset.reload.position}
In RSpec 3 you can setup multiple conditions at once (so the single expectation rule is not broken). It would look sth like:
expect {
click_button 'Save'
@user.reload
}.to change { @user.name }.from('donald').to('gustav')
.and change { @user.updated_at }.by(4)
.and change { @user.great_field }.by_at_least(23}
.and change { @user.encrypted_password }
It is not a complete solution though - as far as my research went there is no easy way to do and_not
yet. I am also unsure about your last check (if it doesn't matter, why test it?). Naturally you should be able to wrap it within your custom matcher.
The accepted answer is not 100% correct since the full compound matcher support for change {}
has been added in RSpec version 3.1.0. If you try to run the code given in accepted answer with the RSpec version 3.0, you would get an error.
In order to use compound matchers with change {}
, there are two ways;
- First one is, you have to have at least RSpec version 3.1.0.
- Second one is, you have to add
def supports_block_expectations?; true; end
into theRSpec::Matchers::BuiltIn::Compound
class, either by monkey patching it or directly editing the local copy of the gem. An important note: this way is not completely equivalent to the first one, theexpect {}
block runs multiple times in this way!
The pull request which added the full support of compound matchers functionality can be found here.