RSpecでスタブを使う
RSpecでスタブを使う方法
RSpecでスタブを使うには、allow(オブジェクト).to receive(:メソッド名).and_return(返り値)
のようにします。
allow
で対象のオブジェクトを,receive
で対象のメソッドを指定します。
それに続けて、and_return
で返り値を指定します。
and_return
の部分は、and_raise
として例外を発生させることもできます。
このほかにも、and_yield
というのもあります。
RSpecでスタブを試す
実際に、RSpecでスタブを試してみます。
まず、今回利用したテストコード全体を貼ります。
class A def doSomething(count) count + 1 end end class B def getCount rand(100) end end RSpec.describe A do a = A.new b = B.new context "スタブを利用しない" do example "doSomethingでインクリメントされる" do count = b.getCount result = a.doSomething(count) expect(result).to eq 1 end end context "スタブを利用する" do example "doSomethingでインクリメントされる" do allow(b).to receive(:getCount).and_return(0) count = b.getCount result = a.doSomething(count) expect(result).to eq 1 end end end
A, Bの二つのクラスがあり、クラスAはdoSomething
で引数をインクリメントして返します。
クラスBは、getCount
で乱数を返します。
クラスBのgetCount
から値を受け取り、クラスAのdoSomething
に渡して、結果をテストします。
ここでの、テスト対象はクラスAとします。
スタブを利用しない場合は、
1) A スタブを利用しない doSomethingでインクリメントされる Failure/Error: expect(result).to eq 1 expected: 1 got: 14 (compared using ==) # ./spec/calc_spec.rb:21:in `block (3 levels) in <top (required)>'
と、テストに失敗しました。
Aに渡す引数は乱数であるため、その結果を正しく検証することができません。
そこで、スタブを利用し、BのgetCount
の返り値を指定します。
ここでは、0を返すようにしています。
allow(b).to receive(:getCount).and_return(0)
こうすると、BのgetCount
は必ず0を返し、AのdoSomething
によりインクリメントされるため1になります。
そして、expect(result). to eq 1
をパスします。
終わり