If you have code that uses DateTime.now you ask yourself "How's my test supposed to pass?" and your pair says "I'd peg it at 1 out of ten times" and if your pair is Rohan Kini you know you have a way out.

Let's set it up right. I have this object:


class User

def initialize
@time_of_birth = DateTime.now
@name = "The dude"
end

def take_over_the_world
p "#{self.name} is taking over the world"
end

end


The tests for which look like


def test_if_use_is_born_with_right_defaults
the_dude = User.new
assert_equal the_dude.time_of_birth, DateTime.now
assert_equal the_dude.name, "The dude"
end


Now obviously a few milliseconds might have past since the execution of User.new so odds are your test will fail even though they should pass.

Here's how you change things around a bit.

In your user class you need to abstract the DateTime.now bit, so you can override things in your test


class User

def date
DateTime.now
end

def initialize
@time_of_birth = date
@name = "The dude"
end

def take_over_the_world
p "#{self.name} is taking over the world"
end

end


And in your test override the new date method you created.

NOW = DateTime.now

class << User

def date
NOW
end

end

def test_if_use_is_born_with_right_defaults
the_dude = User.new # Will use now because you've overridden User::date in the context of this test
assert_equal the_dude.time_of_birth, NOW
assert_equal the_dude.name, "The dude"
end