【发布时间】:2013-10-27 01:59:03
【问题描述】:
我正在使用的编码标准规定,一组测试函数的规范应该有一个主题,即被调用的函数。它看起来像这样:
define User do
context :foo do
let(:user) { FactoryGirl.create(:user) }
subject { user.foo }
it { ... }
end
end
subject 块的典型用途是实例化您正在测试的类:
define User do
subject { FactoryGirl.create(:user) }
it { ... }
end
我们的样式指南的预期效果是,我们为每个正在测试的方法设置了不同的主题块。这会减慢我们的测试速度吗?如果我们以典型方式使用subject,我们是否会受益于内置记忆或其他加速每个类只有一个主题块?
旁白:
我遇到过一种情况,我们的风格不起作用。使用any_instance.should_receive 时,您不能遵循我们的样式指南,否则规范将始终失败。相反,您需要使用更传统的方法,其中 subject 是您正在测试的对象,并在您的规范中调用它的方法。
# passing spec
define Foo do
before { Bar.any_instance.stub(:baz) }
subject { FactoryGirl.create(:foo) }
it "bazzes Bars" do
Bar.any_instance.should_receive(:baz)
subject.baz_the_bars
end
end
# spec follows style guide but fails
define Foo do
before { Bar.any_instance.stub(:baz) }
let(:foo) { FactoryGirl.create(:foo) }
subject { foo.baz_the_bars }
it "bazzes Bars" do
Bar.any_instance.should_receive(:baz)
subject
end
end
class Foo
has_many :bars
def baz_the_bars
bars.collect do |bar|
bar.baz
end.count(true)
end
end
这种风格还有什么我应该注意的问题吗?
【问题讨论】:
-
我可能遗漏了一些东西,为什么您的 Bar 存根会导致问题?主题尚未存在,因此仍应在方法运行之前设置断言。
-
在
before块中,我没有存根Bar。我在Bar的任何实例上存根方法baz()。我的第一遍是:before { Bar.stub(:baz) }这也有效。但是,这并没有通过代码审查,所以我需要修改before块。 -
抱歉,我不清楚 - 我的意思是在所有
Bars 上存根baz。但是,我仍然不明白为什么您的测试失败。您能否更新您的示例以使其可运行?define在这里不是有效的关键字,我认为您可以删除对 ActiveModel 和 FactoryGirl 的引用。也许这也会使问题更容易回答。
标签: rspec subject behaviorsubject