Tuesday, March 18, 2008

Verify Correct DateTime data in method call using NMock

Recently I was writing unit test for a method of the following signature

interface ICache
Insert(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration);

and I wanted to verify the following call -

Insert("key", "value", DateTime.Now.AddMinutes(30), TimeSpan.Zero);

However, you readily see the problem in verifying with the above call for the presence of
DateTime.Now.AddMinutes(30) in the argument. So, a test method like the following won't work for obvious reason.
ICache cache = _mocks.NewMock<ICache>();
Expect.Once.On(cache).Method("Insert").With("key", "value", DateTime.Now.AddMinutes(30), TimeSpan.Zero);

The reason that the above sample code wont work is, my test code called DateTime.Now.AddMinutes(30) before the production code actually did it. So, it is highly probable that the two version of DateTime.Now.AddMinutes(30) in the test code and production code are not same.

To find a work around to this problem, I changed my assumption a little. I set my assumption that the value for the '
absoluteExpiration' parameter must lie in between 29 and 31 minutes from now. So, I modified my test method like the following call-

Expect.Once.On(cache).Method("Insert").With("key", "value", Is.NotNull & Is.AtLeast(DateTime.Now.AddMinutes(29)) & Is.AtMost(DateTime.Now.AddMinutes(31)), TimeSpan.Zero);

This advanced level of NMock usage may show you a way in similar needs. For more insight to this solution, you may wish to visit http://nmock.org/advanced.html