My External Storage

Sep 20, 2017 - 2 minute read - Comments - RubyOnRails

Rspec内でテスト対象のControllerのメソッドの戻り値をスタブする

C#では対象インスタンスのメソッドの挙動を変えることは出来ないので、別の手段を探していたのだが、rubyでは出来た。

TL;DR

  • RSpec書いたControllerSpecの中でテスト対象のコントローラのメソッドの戻り値をモックオブジェクトに変えたかった。
  • ControllerExampleGroupで定義されているcontrollerからテスト中のコントローラインスタンスを操作することが可能

Module: RSpec::Rails::ControllerExampleGroup#controller

前提

rspec-rails (~> 3.0.0.beta2)で確認。

テスト対象のコントローラはこんな感じ。

class MyController < ApplicationController
  def my_client
    MyClient.new
  end
end

controllerallowでメソッドの戻り値をすげ替える

allowを使えばメソッドの挙動をすげ替えることが出来る。Railsの場合はcontrollerを使えばテスト対象のコントローラのインスタンスを得られるので、テストを実行する前に下記の操作をしておくことで、テスト対象のメソッドの挙動も変更しておくことができる。下記の例は、doubleで作成したダミーオブジェクトで、MyController#my_clientの挙動を変更する例。例外を出す例も記載している。

# MyControllerのRSpecのdescribe内

# ダミーオブジェクト作成
my_client_mock = double('Dummy Client')
# メソッドの振る舞いを設定しておく。
allow(my_client_mock).to receive(:my_method).and_return("foo")

# テスト対象のコントローラのメソッドにダミーオブジェクトを設定
allow(controller).to receive(:my_client).and_return(my_client_mock) 
# 例外を出す場合
allow(controller).to receive(:my_client).and_raise(MyError.new('bar')) 

参考

Module: RSpec::Rails::ControllerExampleGroup#controller

Rspec3のexpectとallowの違い

RSpecまとめ(2)~Mock(double/stub/mock)~