【Ruby on Rails】【RSpec】呼び出しごとの返り値を変えるモック

これは何?

  • RSpecでのテストの話
  • モックはしたいが、返り値は固定ではなく呼び出しごとに別の値にしたい場合の書き方を整理
  • 結論は「.orderedを使うのが良い」です

コード例

  • 状況
    • テストしたいクラス・メソッドは、TestTargetService.call
      • TestTargetService.callの内部で、TestSubService.call(json)が3回呼ばれる
  • 方針
    • 可能な限り、テストは他クラスの挙動に依存しない形で用意したい
Ruby
let(:sub_service) { instance_double(TestSubService) }
param1 = ...
param2 = ...
param3 = ...

before do
 # ここからがモック設定
  expect(sub_service).to receive(:call).with(
    hash_including({ name: a_string_including(param1.name) } )
  ).and_return(return_value1).ordered

  expect(sub_service).to receive(:call).with(
    hash_including({ name: a_string_including(param2.name) } )
  ).and_return(return_value2).ordered

  expect(sub_service).to receive(:call).with(
    hash_including({ name: a_string_including(param3.name) } )
  ).and_return(return_value3).ordered
end

describe '#call' do
  subject { TestTargetService.new(user).call }
  it 'test' do
    subject
    # 諸々の確認
  end
end

要点

  • expectの構文の末尾に.orderedを付与した場合、呼び出し回数ごとの挙動の確認が可能
    • 上記の例ではand_return()の後に付与していますが、receive()の後にも付与できます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


This site uses Akismet to reduce spam. Learn how your comment data is processed.