Rspec测试使用模拟和期望从模型的作用域方法中有序检索



我是rspec, mock和stub的新手。我慢慢地开始欣赏和理解隔离测试和模拟/存根的概念。我有一个基本的问题,我认为通过代码更容易解释:

class NewsItem < ActiveRecord::Base
  ...
  scope :ordered, order("created_at DESC")
  ...
end

在我现在的模型测试中,我希望测试返回news_items有序列表的行为。使用FactoryGirl db -touch测试,我实现了如下操作:

# TODO use mocking and stubbing here
it "should have an ordered method to retrieve news items in the descending order" do
  news_item_x = create(:news_item, created_at: DateTime.new(2012,01,01))
  news_item_y= create(:news_item, created_at: DateTime.new(2011,01,01))
  news_item_z= create(:news_item, created_at: DateTime.new(2012,03,01))
  # .all added to avoid comparison failure between groups of NewsItem objects an ActiveRel group.
  expect(NewsItem.ordered.all).to eql([news_item_z, news_item_x, news_item_y])
end 

我不明白如何将上面的测试转换为mock和stub。这是第一次尝试,但显然我误解了一些核心概念。

xit "should have an ordered method to retrieve news items in the descending order" do
  news_item_x = mock(NewsItem, created_at: DateTime.new(2012,01,01))
  news_item_y = mock(NewsItem, created_at: DateTime.new(2011,01,01))
  news_item_z = mock(NewsItem, created_at: DateTime.new(2012,03,01))
  NewsItem.should_receive(:ordered).and_return([news_item_z, news_item_x, news_item_y])
  # NewsItem.should_receive(:ordered).ordered # not working.
  # this is pointless as it's not checking the order of anything, just the call.
  NewsItem.ordered
end 

嘲弄/存根在这种测试中是否合适?

如有任何建议,不胜感激。

结论:

我从@arieljuod和@zetetic那里得到了一些很棒的答案。对于我最初的问题,嘲讽和存根在这里合适吗?正如@zetetic指出的那样,答案似乎是否定的。

另一方面,@arieljuod提供了一种非常好的方法来实际测试我的代码片段(不一定要通过mock和stub)。

在这种测试中嘲弄/存根是否合适?

使用模拟和存根的目的是将编写的代码与其依赖项隔离开来。在scope的情况下,它所依赖的一切都隐藏在Rails框架中。此外,您不需要首先测试框架/库代码的内部——原始作者已经完成了。

您应该只测试您的"ordered"作用域在以"created_at DESC"作为参数的模型上调用"order",至少在那个简单的示例

上是这样。
describe 'ordered' do
  it 'orders by created_at desc' do
    NewsItem.should_receive(:order).once.with('created_at DESC')
    NewsItem.ordered
  end
end

你可以相信查询会有你想要的顺序

更复杂的作用域可能需要其他规范,但是你总是可以把复杂的作用域分解成更小的作用域来正确地测试它们,并且只有在作用域不是微不足道的时候才做一个真正的数据库查询(就像你首先实际创建对象并运行查询一样)(如果你做了一些奇怪的手动SQL查询,你应该测试它做了你想要的,否则,信任rails)

编辑:如注释所述,该代码不起作用,您可以检查ActiveRelation对象是否具有所需的顺序集:

describe 'ordered' do
  it 'orders by created_at desc' do
    NewsItem.ordered.order_values.should == ['created_at DESC']
  end
end

这样你就知道活动关系会在查询

上使用那个顺序

相关内容

  • 没有找到相关文章

最新更新