久々にちょっとレアケースな感じの rspec 書いたら上手く動かずハマりました
一回目は例外出したいけど二回目からは出したくない、的な。
具体的には DynamoDB の WriteCapacity を超えてしまった際に時間を少し開けてリトライさせる処理のテストです。
テスト対象のコード(簡略化したもの)
def call
hoge.fuga
rescue PiyoError
retry
end
上手く行かなかったやつ。
before do
allow(hoge).to(receive(:fuga)).once do
raise PiyoError
end
end
it do
subject
expect(line_user).to have_received(:update_latest_talk_cache!).twice
end
- See: Block implementation - Configuring responses - RSpec Mocks - RSpec - Relish
allow(dbl).to receive(:foo).once { do_something }
動作的には 1 回だけ raise されるようになるが、 expect で 1 回しか実行していない、と怒られる。
恐らく fuga
が 1 回目の実行分しか spy オブジェクトにならないんだと思う。
結局こうした。
before do
@count = 0
allow(hoge).to(receive(:fuga!)) do
if @count.zero? # NOTE: 一度目の実行のみ例外を出す
@count += 1
raise PiyoError
end
end
end
it do
subject
expect(line_user).to have_received(:update_latest_talk_cache!).twice
end