Ordering by created_at in unit tests with generated data in rails
mysql, ruby, ruby-on-rails, unit-testing
Solution
DigitalRoss is right. `created_at` has a one second granularity.
One option is to set the `created_at` when you create the objects:
old = EditItem.new(:created_at => 1.second.ago)
older = EditItem.new(:created_at => 2.seconds.ago)
Another option is to actually use stubbing to mess with the `Time` class. The following would work with Rspec, but could be easily accomplished with other mocking frameworks like Mocha.
@seconds = Time.now.to_i
Time.stub!(:now).and_return{Time.at(@seconds += 5) }
This will return a time 5 seconds greater than the previous each time you call `Time.now`.
I'd recommend the first approach if you can make it work, since it's more clear what you're doing and less likely to have unintended consequences.
Problem
I have a bit of code that basically displays the last x (variable, but let's say x is 20 here) updates made in a given table. In one of the unit tests for it, I have this snippet: ``` 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} ``` May or may not be pretty, but it gets the intention across. The hiddennow object has been pushed down in the queue too far and should no longer be returned when get_entries is called. ``` #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") ``` This is simplified down a bit, but it looks like the 20.times loop adds things fast enough that the order by clause on created_at cannot distinguish. My questions are, am I doing something fundamentally wrong? If not, what is the better approach to writing a test along these lines?