【发布时间】:2018-12-15 05:27:48
【问题描述】:
一个失败的测试让我质疑我对什么是测试替身的理解(测试框架是 RSpec)。
据我了解:
模拟是一个假对象,代表被测对象的合作者
假设我有一个Person 类:
class Person
def default_number_of_products
Product.new
end
end
和 Product 类:
class Product
def initialize
@default_number = 3
end
end
为了测试对 Person 调用 default_number_of_products 会导致 Product 接收到 new,我编写了一个如下所示的测试:
RSpec.describe Person do
let(:person) { Person.new }
describe '#default_number_of_products' do
it 'invokes new on product' do
product = double(Product)
expect(product).to receive(:new)
person.default_number_of_products
end
end
end
失败并返回此错误:
// ♥ rspec spec/lib/person_spec.rb
F
Failures:
1) Person#default_number_of_products invokes new on product
Failure/Error: expect(product).to receive(:new)
(Double Product).new(*(any args))
expected: 1 time with any arguments
received: 0 times with any arguments
# ./spec/lib/person_spec.rb:23:in `block (3 levels) in <top (required)>'
Finished in 0.01006 seconds (files took 0.1052 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/lib/person_spec.rb:21 # Person#default_number_of_products invokes new on product
另一方面,下面的测试通过了:
RSpec.describe Person do
let(:person) { Person.new }
let(:product) { Product }
describe '#default_number_of_products' do
it 'invokes new on product' do
expect(product).to receive(:new)
person.default_number_of_products
end
end
end
问题:
- 我认为可以通过使用双精度对象来消除对协作对象的依赖——这样,无需实现协作类即可编写测试。上述结果表明 我的理解不太对。请问我缺少什么?
【问题讨论】: