RSpec/MessageSpies

メソッドスパイした後に、have_received を使えということらしい。

# bad
expect(foo).to receive(:bar)

# good
expect(foo).to have_received(:bar)

下記でいうと、同じ意味のテストにはなるが、後者のテストとしては意図が明確でよい、ということらしい。

expect(foo).to receive(:bar)

# exercise system under test

expect(foo).to receive(:bar)
allow(foo).to receive(:bar)

# exercise system under test

expect(foo).to have_received(:bar)

は同じです。

前者はモック時に :bar が呼び出されたかどうか?を記述しています。 これは Given / When / Then でいうなら Given の際に Then の内容を記述していることになります。

それに対して後者は Given と Then が明確にわかれています。 この方が好ましいだろう、というのが MessageExpectation が意図するところです。

rubocop-rspecのMessageExpectation CopとGiven/When/Then - Tbpgr Blog