RSpec: double, stub, stub_chain, etc. -- cheat sheet

double

あるメソッドを持ったオブジェクトを作る。doubleは「代役」の意。


user = double("user", name: "Taro")
user.name #=> "Taro"

第1引数の "user"RSpecが失敗を報告するのに使うラベルに過ぎない(省略可)。


mock および stub というエイリアスがある。

stub

あるオブジェクトの特定のメソッドが特定の値を返すように、オブジェクトを作り替える。


User.stub(:find) { double("user", name: "Taro") }
u = User.find(1)
u.name #=> "Taro"

stub_chain

メソッドチェーン対応版のstub


User.stub_chain(:where, :find) { double("user", name: "Taro") }
u = User.where(deleted: false).find(1)
u.name #=> "Taro"

should_receive

基本的にはstubと同じ。ただし、エグザンプルの終わりまでに少なくとも1回呼ばれたかどうかがチェックされる。


User.should_receive(:find) { double("user", name: "Taro") }
u = User.find(1)
u.name #=> "Taro"

as_null_object

あるオブジェクトが、どのようなメソッドを呼ばれようとも自分自身を返すように、オブジェクトを作り替える。


User.stub(:find) { double("user").as_null_object }
u = User.find(1)
u.activated? #=> u

mock_model

ActiveModelインスタンスのように振る舞うオブジェクトを作る。


manager = mock_model("Manager", name: "Jiro")
manager.name #=> "Jiro"
expect(manager).to be_valid

stub_modelと異なり、まだモデルクラスが実装されていなくてもよい。

stub_model

ActiveModel クラスのインスタンスを作って、それを stub する。


manager = stub_model(Manager, name: "Jiro")
manager.name #=> "Jiro"
expect(manager).to be_valid

mock_modelと異なり、stub しなかったメソッドは、本物のモデルクラスが答えてくれる。

as_new_record

対象オブジェクトの persisted? メソッドが false を返すように stub する。


manager = stub_model(Manager, name: "Jiro")
manager.name #=> "Jiro"
expect(manager).to be_valid