自从我开始使用rspec以来,我遇到了固定装置概念的问题.我主要担心的是:
我使用测试来揭示令人惊讶的行为.对于我正在测试的示例,我并不总是能够枚举每个可能的边缘情况.使用硬编码灯具似乎有限,因为它只用我想象的非常具体的情况来测试我的代码.(不可否认,我的想象力也限制了我测试的情况.)
我使用测试作为代码的文档形式.如果我有硬编码的夹具值,很难揭示特定测试试图演示的内容.例如:
describe Item do
describe '#most_expensive' do
it 'should return the most expensive item' do
Item.most_expensive.price.should == 100
# OR
#Item.most_expensive.price.should == Item.find(:expensive).price
# OR
#Item.most_expensive.id.should == Item.find(:expensive).id
end
end
end
Run Code Online (Sandbox Code Playgroud)
使用第一种方法给读者没有指示最昂贵的物品是什么,只是它的价格是100.所有三种方法都要求读者认为夹具:expensive是最昂贵的物品fixtures/items.yml.粗心的程序员可以通过创建Itemin before(:all)或通过插入另一个fixture 来中断测试fixtures/items.yml.如果这是一个大文件,可能需要很长时间才能弄清问题是什么.
我开始做的一件事是#generate_random为我的所有模型添加一个方法.此方法仅在我运行规范时可用.例如:
class Item
def self.generate_random(params={})
Item.create(
:name => params[:name] || String.generate_random,
:price => params[:price] || rand(100)
)
end
end
Run Code Online (Sandbox Code Playgroud)
(我这样做的具体细节实际上有点清晰.我有一个类来处理所有模型的生成和清理,但是这个代码对于我的例子来说足够清楚了.)所以在上面的例子中,我可能会测试为如下.佯装的警告:我的代码在很大程度上依赖于before(:all):
describe Item do
describe '#most_expensive' do
before(:all) do
@items = [] …Run Code Online (Sandbox Code Playgroud)