On 2009-09-16, at 08:08 , David Chelimsky wrote:

On Wed, Sep 16, 2009 at 3:34 AM, Ramon Tayag <ramon.ta...@gmail.com> wrote:
I put an expectation test, but it complains two things are different
when it prints it out in the error in the exact same way:
http://pastie.org/618481

Printing is printing. Time is _not_ time. The problem is that the
times are off by milliseconds that aren't accounted for in time.to_s.

The usual solution is to either stub Time.now or introduce a time
generator, but you're not using Time.now, so that won't work. Options
include:

1. examine the submitted argument directly

@orders.should_receive(:updated_on) do |actual|
 expected = 1.week.ago.to_i
 actual.to_i.should be_between(expected - 1000, expected)
end

That will expect the time within 1 second of 1.week.ago.

2. introduce a custom argument matcher

class Roughly
 def initialize(expected)
   @expected = expected.to_i
 end

 def ==(actual)
   actual.to_i.between?(@expected - 1000, @expected)
 end
end

def roughly(expected)
 Roughly.new(expected)
end

@orders.should_receive(:updated_on).with(roughly(1.week.ago))

And for extra credit, you can even make this one more flexible and
provide a lower and upper bound using a fluent interface:

@orders.should_receive(:updated_on).with(within(1.second).of (1.week.ago))

I highly recommend a small refactoring to increase the clarity of your code and reduce the coupling with the system clock. I posted my suggestion at http://pastie.org/619142.

By doing this, you make it easy to stub/expect @orders in your #process_aftersale test, and make it easy to test #ready_for_aftersale_letter without wanting to use a stub or mock. To test #ready_for_aftersale_letter, simply use 1.week.ago, 8.days.ago and 6.days.ago as your test cases. Noticing this, you probably want to try 7.days.ago + 1.millisecond and make sure that behaves the way you'd expect, because you probably want to ensure that you use 1.week.ago.at_midnight, and not just 1.week.ago.

Question: if I buy from you on September 15, 2009 at 17:50, when is my order ready for an aftersale letter? (a) September 22, 2009 at 17:50, (b) September 22, 2009 at 00:00, (c) September 22, 2009 at 09:00, (d) September 23, 2009 at 00:00, or some other time entirely? Write a test for that.

Take care.
----
J. B. (Joe) Rainsberger :: http://www.jbrains.ca
Your guide to software craftsmanship
JUnit Recipes: Practical Methods for Programmer Testing
2005 Gordon Pask Award for contributions to Agile Software Practice

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to