RSpec.describe 'double' do
let(:store) { double('store', sell: 'earn the money!')}
it 'should invoke method first' do
expect(store.sell).to eq('earn the money!')
end
end
RSpec.describe 'spies' do
let(:burger) { spy('burger') }
it 'confirm a message has been received' do
burger.eat
expect(burger).to have_received(:eat)
end
end
RSpec.describe 'spies' do
let(:burger) { spy('burger') }
it 'confirm a message has been received' do
burger.eat
expect(burger).to have_received(:eat)
expect(burger).to have_received(:throw)
end
end
class Cheese
def initialize(type)
@type = type
end
end
class Burger
attr_reader :cheese
def initialize
@cheese = []
end
def add(type)
@cheese << Cheese.new(type)
end
end
RSpec.describe Burger do
let(:cheese) { spy(Cheese) }
before do
allow(Cheese).to receive(:new).and_return(cheese)
end
describe '#add' do
it 'add cheese to burger' do
subject.add('parmesan')
expect(Cheese).to have_received(:new).with('parmesan')
expect(subject.cheese.length).to eq 1
expect(subject.cheese.first).to eq(cheese)
end
end
end
我們逐行來解釋一下,首先在進入測試之前( 第五行 ),我們先做了允許 Cheese 這個類別接收 new 方法,並且 return 我們的 spy(Cheese)
接著我們又說這個 Cheese 已經接受了 new 方法,也就是我們在 before block 中所做的事情,在這個時候,我們已經徹底的替換掉正式的程式碼了。
接著的 expectation 就是基本的操作囉~
但你會發現,這個 spy 替換成 instance_double 也能夠正常的使用。
奇怪了… 那我們印出來看看吧!我們先印印看 spy 版本的
spy version
ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
RSpec.describe Burger do
let(:cheese) { spy(Cheese) }
before do
allow(Cheese).to receive(:new).and_return(cheese)
end
describe '#add' do
it 'add cheese to burger' do
subject.add('parmesan')
expect(Cheese).to have_received(:new).with('parmesan')
p cheese # 印出來看看吧
expect(subject.cheese.length).to eq 1
expect(subject.cheese.first).to eq(cheese)
end
end
end
有沒有搞錯?這個 spies 講得這麼厲害,但結果是 double 的語法糖衣嗎?
我們快印看看 instance double 是什麼?
instance version
ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
RSpec.describe Burger do
let(:cheese) { instance_double(Cheese) }
before do
allow(Cheese).to receive(:new).and_return(cheese)
end
describe '#add' do
it 'add cheese to burger' do
subject.add('parmesan')
expect(Cheese).to have_received(:new).with('parmesan')
p cheese # 印出來看看吧
expect(subject.cheese.length).to eq 1
expect(subject.cheese.first).to eq(cheese)
end
end
end