【问题标题】:rspec expects doesn't do what I expectrspec 预期不符合我的预期
【发布时间】:2013-02-05 18:53:10
【问题描述】:

所以我有两个规格,我认为它们正在测试相同的东西,但一个失败而另一个通过。我正在开发一个具有重复计划的应用程序。如果用户创建重复的行程,它将继续并为指定的每一天创建新行程。这是第一个失败的测试:

it "makes future trips" do
  expect{FactoryGirl.create(:recurring_transportation_trip)}.to change(Trip, :count).by(4)
end

recurring_transportation_trip 创建一个行程,它将通过 after_save 回调进行三个未来行程。此测试失败,并出现错误“count should have changed by 4, but was changed by 1”。

这是另一个通过的测试:

it "makes future trips" do
  count = Trip.count
  FactoryGirl.create(:recurring_transportation_trip)
  Trip.count == count + 4
end

表明存在正确的功能。

第一个测试当然更具可读性,但实际上并没有测试我认为它做了什么。任何人都可以提供并解释原因吗?

-------编辑-------

按要求添加工厂代码:

FactoryGirl.define do
  factory :recurring_transportation_trip, :class => :trip do
    collection_time "09:00"
    estimated_duration "60"
    status "Confirmed"
    mileage "30"
    association :collection, :factory => :location
    association :destination, :factory => :location
    association :call, :factory => :recurring_call
  end
end

对于 recurring_call

FactoryGirl.define do
  factory :recurring_call, :class => "Call" do
    recurring true
    recurring_start_date Date.today
    recurring_end_date Date.today + 1.week
    recurring_config [1, 3, 5]
  end
end

-------EDIT2-------

原来Trip.count == count + 4 实际上并没有断言任何东西,而测试Trip.count.should == count + 4 确实失败了。感谢@BenediktDeicke 指出这一点。

-------EDIT3-------

最后这是我的应用程序代码中的一个错误,我应该从一开始就信任原始测试。感谢所有看过的人。 @boulder 和 @BenediktDeicke 感谢您指出 edit2 中提到的缺少断言。

【问题讨论】:

  • 如果你使用 change{Trip.count} 而不是 change(Trip, :count) 这样会发生什么:expect{FactoryGirl.create(:recurring_transportation_trip)}.to change{Trip.count}.by(4) 同样的问题?
  • @pjam 将 change(Trip, :count) 更改为 change{Trip.count} 给出相同的结果(只是注意到块 =p)
  • 确实很奇怪,你能发布你工厂的代码吗?
  • @pjam 刚刚编辑了我之前的评论。没注意到Trip.count 在一个街区^.^
  • 另一个测试通过了,因为里面没有任何断言。所以很可能这种行为不是你想象的那样。将 Trip.count == count + 4 更改为 Trip.count.should == count + 4 以查看它 - 很可能 - 失败

标签: ruby-on-rails ruby unit-testing rspec factory-bot


【解决方案1】:

您的第二个测试实际上并没有测试任何东西,因为它没有定义任何期望。

线 Trip.count == count + 4 只是一个计算结果为假的表达式。

你想要做的是:

Trip.count.should == count + 4

无论如何,第一个测试是您应该信任的;它告诉您您的应用程序代码中存在需要调查的错误。

【讨论】:

  • 你刚刚在我写我的问题前几秒钟编辑了你的问题,这使它过时了。如果您向我们展示您的模型回调,我们可能会告诉您为什么它们没有按预期工作。
  • 谢谢。这是正确的答案。我实际上发现了错误,这是应用程序代码的问题。但是,更好地理解 rspec 中的期望正是我所要求的,我只是没有意识到。也归功于@BenediktDeicke
【解决方案2】:

by 链匹配器是预期应该改变的量。

expect{FactoryGirl.create(:recurring_transportation_trip)}.to change(Trip, :count).by(1)

这里是documentation

【讨论】:

  • 对不起,我仍然很困惑,FactoryGirl.create(:recurring_transportation_trip) 应该进行一次旅行,其中有一个 after_save 回调可以再进行三次。因此,我希望 Trip 计数改变 4 而不是 1。