可能重复:
RSpec 是否有可能期望在两个表中发生变化?
it "should create a new Recipe" do
expect { click_button submit }.to change(Recipe, :count).by(1)
end
这使我可以检查“食谱”模型是否还有一个条目,但我还想检查“成分”模型是否还有一个条目。expect 块只能执行一次,因为表单已经提交。
我知道我可以再做一个“它”块,但我觉得必须有一个 DRYer 方法。
可能重复:
RSpec 是否有可能期望在两个表中发生变化?
it "should create a new Recipe" do
expect { click_button submit }.to change(Recipe, :count).by(1)
end
这使我可以检查“食谱”模型是否还有一个条目,但我还想检查“成分”模型是否还有一个条目。expect 块只能执行一次,因为表单已经提交。
我知道我可以再做一个“它”块,但我觉得必须有一个 DRYer 方法。
我建议通过重新定义测试对象(并使用stabby lambdas来获得乐趣)来干燥它:
describe "recipe creation" do
subject { -> { click_button submit } }
it { should change(Recipe, :count).by(1) }
it { should change(Ingredient, :count).by(1) }
end
更新:虽然它可能看起来不那么 DRY,但这些天我可能仍会继续使用该expect
语法,因为它是推荐的,而且我通常会远离should
,但可能会为规范可读性做一些小改动:
describe "recipe creation" do
let(:creating_a_recipe) { -> { click_button submit } }
it "changes the Recipe count" do
expect(creating_a_recipe).to change(Recipe, :count).by(1)
end
it "changes the Ingredient count" do
expect(creating_a_recipe).to change(Ingredient, :count).by(1)
end
end
注意:您可能会在RSpec 文档中change
看到expect
使用大括号的匹配器。这当然是正确的,但标准括号在此示例中起作用的原因是更改可变状态(包含在 中)的代码位于作为参数creating_a_recipe
传入时被调用的 lambda 中。expect
无论如何,在这种情况下,expect(creating_a_recipe)
或者expect { creating_a_recipe }
可以成功使用,您使用哪个取决于个人喜好。
您可以将所有这些抽象为辅助方法
def test_creation_of(model)
it "should create a new #{model}" do
expect { click_button submit }.to change(model.constantize, :count).by(1)
end
end
但我只推荐它,如果你会为许多模型这样做。否则只会使代码更难阅读。如果这样做,最好将其放入规范助手中。
此外,根据您测试中的其他先例,您可以传递一个 Const 对象而不是字符串(正如我在上面的示例中使用的那样)。
然后
it "should create a new Recipe" do
test_creation_of( 'Recipe' )
test_creation_of( 'Ingredient' )
end