Rspecでインスタンスメソッドのテストに苦労したのでメモ
今回はRspecでメソッドのテストをしたかったのですが、メソッド内で定義しているメソッド先の処理のテストは記述したくなかったので、それを解決したメモになります。
rubyのコード
# 今回テストしたかったのはTest1のexecuteメソッドになります Class Test1 def self.execute(test_params) Test2.execute(test_params) Test3.new(test_params).execute(test_params) # ←こいつが一番の曲者でした end end Class Test2 def self.execute(test_params) p test_params + 'test2' end end Class Test3 def initialize(test_params) @test = test_params + 'test3' end def execute(test_params) p @test + test_params + 'test3' end end
テストコード
require 'rails_helper' RSpec.describe Test1 do describe 'テスト1' it 'interfaceのテスト' test = double('Test3:00000000') allow(Test2).to receive(:execute).and_return(true) allow(Test3).to receive(:new).and_return(test) allow(Test3.new("")).to receive(:execute).and_return(true) Test1.execute(anything) end end end
Test3のテストコードですが、。最初は下記のように記述していました。
allow(Test3).to receive(:new) allow(Test3.new("")).to receive(:execute)
↑だとexecuteを呼ぶ時にno method errorがでます。
Test3で定義しているexecuteはクラスメソッドではなくインスタンスメソッドなので、インスタンスにメソッドを定義しないとエラーが出てしましました。
なので、
test = double('Test3:00000000')
↑でインスタンスを定義して
allow(Test3).to receive(:new).and_return(test)
↑でnewした時の戻り値にインスタンスを返えすようにします。
allow(Test3.new("")).to receive(:execute)
↑でインスタンスにexecuteメソッドを定義することによって
Class Test1 def self.execute(test_params) Test2.execute(test_params) Test3.new(test_params).execute(test_params) # ←こいつのテストが通るようになる end end
Test3のテストが通るようになります。(解決するまでにめっちゃ時間がかかりました。