woshidan's loose leaf

ぼんやり勉強しています

テスト中のオブジェクトに実際の動作をさせないで返り値を指定する

特定のオブジェクトにあるメソッドの中身を実行せず結果だけ返して欲しい場合

allowとreceiveを使ってスタブの指定をします。

allow(some_object).to receive(:method_name).and_return(return_value)

特定のクラスのインスタンス全てにあるメソッドの中身を実行せず結果だけ返して欲しい場合

allow_any_instance_of(ClassName).to receive(:method_name).and_return(return_value)

以下のようなコントローラのアクションに対するテストなどでテストコードではないところで生成するインスタンスに対して

# コントローラのコード
def index
  api_client = SomeApiClient.new(token)
  @result = api_client.search # 外部APIへリクエストを飛ばす
end
# テストコード
allow_any_instance_of(SomeApiClient).to receive(:search).and_return(["foo", "bar"])

といった具合に使います。

引数があるメソッドの場合に引数を指定したい場合

メソッドの呼び出しに伴う引数を指定したい場合はwithを使います。

allow(some_object).to receive(:method_name).with(arg).and_return(return_value)

複数の引数を指定したい場合は

allow(some_object).to receive(:method_name).with(arg1, arg2, ...).and_return(return_value)

どの引数を受け取ってもいい場合は

allow(some_object).to receive(:method_name).with(anything()).and_return(return_value)

この引数にはハッシュの一部だけを指定したりいろんなバリエーションがあります。

relishapp.com

例外を起こしたい場合

and_raiseを使います。

allow(some_object).to receive(:method_name).and_raise(SomeError.new)

参考

relishapp.com