Monday, July 31, 2006

Redefine for consistent test results

Today I was looking at some code that used a class called Environment. The Environment class was used to specify a date based on what environment the code was executing in. In production the Environment class would simply return; however, when Environment was used in a test it always returned the value, 1, 23, 13, 14, 15).

This can be particularly important if you are working with code similar to this:
class Comment
attr_reader :created_at

def initialize
@created_at =
In the example, you would like a test that proves that the created_at instance variable is set in the constructor, such as:
class CommentTest < Test::Unit::TestCase
def test_ctor_inits_created_at
Unfortunately, this test doesn't work correctly if the DateTime instances aren't created at exactly the same point in time.

To solve this problem the Environment class was designed to allow you to specify a date in the expected results of a test without being concerned if it matched the current date or not. The Environment solution worked, but it wasn't particularly elegant.

We decided to refactor to what we thought was a simpler solution. We added the following code directly to the test class.
class << DateTime
def now, 1, 23, 13, 14, 15)
By redefining the now method we were able to reliably assert equality. This change removed the need for the Environment class also. Of course, will always return this date for all the tests that follow this one; we were comfortable with all the tests depending on this constant value.
Post a Comment