2

If I want to test, that an operation produces certain side-effects, how can I execute the operation once and use the change rspec matcher. Example:

expect { some_method }.to change(Foo, :count).by(1)
expect { some_method }.to change(Bar, :count).by(1)
expect { some_method }.to change(Baz, :count).by(1)

How can I execute some_method only once, instead of 3 times?

Or do I need to do something like:

foo_count_before = Foo.count
bar_count_before = Bar.count
baz_count_before = Baz.count

some_method

foo_count_after= Foo.count
bar_count_after= Bar.count
baz_count_after= Baz.count

expect(foo_count_after - foo_count_before).to eq 1
expect(bar_count_after - bar_count_before).to eq 1
expect(baz_count_after - baz_count_before).to eq 1
Alexander Popov
  • 23,073
  • 19
  • 91
  • 130

1 Answers1

8

You can join multiple expectations together using compound expectations. In your example, this can look like this:

expect { some_method }
  .to change(Foo, :count).by(1)
  .and change(Bar, :count).by(1)
  .and change(Baz, :count).by(1)
Holger Just
  • 52,918
  • 14
  • 115
  • 123
  • Thank you. Also, a brand new article on the subject: https://robots.thoughtbot.com/chain-rspec-matchers-for-improved-test-readability?utm_source=rubyweekly&utm_medium=email – Alexander Popov Mar 31 '17 at 04:58
  • Brilliant! I make a code cleaner. Thank you very much – Penguin Oct 01 '18 at 06:41