我是rspec的新手,嘲笑和抄袭。我慢慢开始欣赏并总体上围绕着孤立测试和嘲讽/存根的概念。我有一个基本问题,我认为通过代码更容易解释:
class NewsItem < ActiveRecord::Base
...
scope :ordered, order("created_at DESC")
...
end
在我的模型测试中,我希望测试返回news_items的有序列表的行为。使用FactoryGirl DB触摸测试,我实现如下:
# 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
我无法理解如何将上述测试转换为模拟和存根。这是第一次尝试,但显然我在这里误解了一些核心概念。
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提供了一种非常好的方法来实际测试我的代码片段(不一定是通过模拟和存根)。这两个都是有效的答案。
答案 0 :(得分:2)
在这种测试中,嘲讽/吟唱是否合适?
没有
使用模拟和存根的目的是将您写入的代码与其依赖项隔离开来。在scope
的情况下,它依赖的所有内容都隐藏在Rails框架中。此外,您不应该首先测试框架/库代码的内部 - 原始作者已经这样做了。
答案 1 :(得分:1)
你应该只测试你的“有序”范围在模型上用“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
通过这种方式,您知道活动关系将在查询中使用该顺序