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

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

RSpec 実例

まとめるとこんな感じで書けということ。

before
  allow(Foo).to receive(:bar)
end

it "Foo.bar が一度呼ばれること" do
  expect(Foo).to have_received(:bar).once
end