在单个lambda请求中断言多个更改期望

时间:2011-09-28 14:44:22

标签: rspec2

我有这样的测试:

lambda { post("/api/users", parameters) }.should change(User,:count).by(1)
lambda { post("/api/users", parameters) }.should_not change(ActionMailer::Base, :deliveries)

但我想这样做:

lambda { post("/api/users", parameters) }.should change(User,:count).by(1).and_not change(ActionMailer::Base, :deliveries)

是否可以在不需要两次调用的情况下完成?

由于

3 个答案:

答案 0 :(得分:11)

我找到了一个测试它的解决方案。

lambda{
  lambda { post("/api/users", params) }.should change(User,:count).by(1)
}.should change(ActionMailer::Base.deliveries, :count).by(1)

答案 1 :(得分:2)

在我的测试中,我非常严格:我希望每个测试只测试一件事。所以我总是选择第一种形式,而不是第二种形式。

其次,我不确定技术上是否可行。 .should需要一个块,它在lambda之前和之后执行。无论如何,据我所知,目前rspec并不支持这一点(而且有充分的理由)。

答案 2 :(得分:0)

我最近在将一些request测试迁移到Capybara 2.1的feature测试格式,并将测试语法从should - 基础转换为{{1}时遇到此问题}为基础的。要使用原始问题作为示例,我的代码如下:

expect

subject { -> { post("/api/users", parameters) } } it { should change(User,:count).by(1) } it { should_not change(ActionMailer::Base, :deliveries) } 测试中将此转换为expect语法会出现一些问题并产生这种(工作)笨拙(抱歉,不是明确嵌套scenario s /的忠实粉丝lambda S):

expect

this StackOverflow thread中有一些很好的解决方案可以解决这个问题,但我最终做的只是简单地遵循原始格式并将每个语句拆分为自己的expect(-> { expect(post("/api/users", parameters)).to change(User,:count).by(1) } ).to_not change(ActionMailer::Base, :deliveries) ;类似的东西:

scenario

比原始feature "Add users via API" do given(:posting_parameters_to_api) { -> { post("/api/users", parameters) } } scenario "foo" do expect(posting_parameters_to_api).to change(User,:count).by(1) end scenario "bar" do expect(posting_parameters_to_api).to_not change(ActionMailer::Base, :deliveries) end end 规范更详细,但基本上以相同的方式工作。实施可能归结为个人品味。