我有一些代码基本上显示了在给定表中所做的最后一个 x(变量,但假设这里 x 为 20)更新。在它的一个单元测试中,我有这个片段:
EditedItem.push_to_queue(hiddennow)
#create some new entries and save them
20.times{ EditedItem.push_to_queue(random_item) }
Queue.get_entries.each{|entry| assert_not_equal too_far_down, entry}
可能漂亮也可能不漂亮,但它传达了意图。 hiddennow 对象在队列中被推得太远,调用 get_entries 时不应再返回。
#this works
SearchObject.find(:all, :order => "id desc")
#this does not, unless the 20.times loop has sleep(1) or something
SearchObject.find(:all, :order => "created_at desc")
这稍微简化了一点,但看起来 20.times 循环添加内容的速度足够快,以至于 created_at 上的 order by 子句无法区分。我的问题是,我是否做错了根本性的事情?如果不是,按照这些思路编写测试的更好方法是什么?
最佳答案
DigitalRoss 是对的。 created_at
具有一秒粒度。
一个选项是在创建对象时设置 created_at
:
old = EditItem.new(:created_at => 1.second.ago)
older = EditItem.new(:created_at => 2.seconds.ago)
另一种选择是实际使用 stub 来扰乱 Time
类。以下内容适用于 Rspec,但可以使用其他模拟框架(如 Mocha)轻松完成。
@seconds = Time.now.to_i
Time.stub!(:now).and_return{Time.at(@seconds += 5) }
每次您调用 Time.now
时,这将返回比前一个时间长 5 秒的时间。
如果您可以使用第一种方法,我会推荐它,因为它更清楚您在做什么,并且不太可能产生意想不到的后果。
关于mysql - 在 rails 中生成数据的单元测试中按 created_at 排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1738326/