在测试文献中,您听说不要在传出消息上断言,除非他们改变其他内容的状态。换句话说,不影响状态的查询消息存在allow().with().and_return()
。
我对这个方法的问题是,当所有这些允许在前一个块中发生时,当一个方法的参数发生变化时,每个测试都会失败。这是因为不会触发allow().with()
块。
考虑这个例子:
describe('#some_endpoint') do
let(:another_class) { instance_double(AnotherClass) }
let(:presenter) { instance_double(Presenter) }
before do
allow(another_class).to receive(:presenter).with(some_args).and_return(presenter)
end
it 'assigns the correct presenter' do
get :some_endpoint
expect(assigns(:presenter)).to eq(presenter)
end
it 'responds with ok status' do
get :some_endpoint
expect(subject).to have_http_status(:ok)
end
it 'does something else' do
.....
end
end
此示例遵循测试文献,并且未在another_class.presenter
上断言,因为这是查询消息。但是,如果演示者的预期参数some_args
在代码中发生更改,则所有测试都将失败。如果只有assigns the correct presenter
测试失败,这就更容易调试,这是参数更改时的实际失败;因为返回的演示者不是正确的演示者。以下测试将实现该目标:
describe('#some_endpoint') do
let(:another_class) { instance_double(AnotherClass) }
let(:presenter) { instance_double(Presenter) }
before do
allow(another_class).to receive(:presenter).and_return(presenter)
end
it 'assigns the correct presenter' do
get :some_endpoint
expect(another_class).to have_received(presenter).with(some_args)
expect(assigns(:presenter)).to eq(presenter)
end
it 'responds with ok status' do
get :some_endpoint
expect(subject).to have_http_status(:ok)
end
it 'does something else' do
.....
end
end
以这种方式测试有哪些缺点?我只看到优点。如果是这种情况,为什么测试社区建议不测试查询消息?