Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a time - based component?

So I'm writing a cache system (not too complicated, but it has very nice semantics) with a ttl (time to live) for items.

Of course the ttl must be unit tested, but since one can't inject a new implementaton of "IDateTime" or "ITimeSpan" in C# (because there is no such thing), how would you go about that?

Write a new component "IDateTimeProvider" and "DateTimeProvider" first, which one can mockup then?

Isn't reimplementing parts of the .NET runtime library... overkill?

Edit: Thank you all for your amazing answers! I know now exactly what I'm going to do!

like image 327
StormianRootSolver Avatar asked Jun 25 '10 08:06

StormianRootSolver


People also ask

What are the components of unit testing?

Component Testing involves testing each object or part of the software separately. Unit Testing involves testing individual programs or modules for program execution. 2. It is performed by the testing team.

What is unit testing with real time example?

An example of a real-world scenario that could be covered by a unit test is a checking that your car door can be unlocked, where you test that the door is unlocked using your car key, but it is not unlocked using your house key, garage door remote, or your neighbour's (who happen to have the same car as you) key.

What are the two types of unit testing?

There are 2 types of Unit Testing: Manual, and Automated.

Does unit testing save time?

Unit testing results in quality software This ensures a reliable engineering environment where quality is paramount. Over the course of the product development life cycle, unit testing saves time and money, and helps developers write better code, more efficiently.


4 Answers

I usually use a variation of Ayende's solution.

public static class SystemTime
{
    public static Func<DateTime> DateProvider = () => DateTime.Now;

    public static DateTime Now { get { return DateProvider(); } }
}

In the code under test you can now use SystemTime.Now to get the current time:

var currentTime = SystemTime.Now;

And in the test you can set the current time to a known value:

SystemTime.DateProvider = () => new DateTime(2010,6,25);
like image 167
PHeiberg Avatar answered Oct 14 '22 07:10

PHeiberg


You might want to see this question:

How do I MOQ the System.IO.FileInfo class... or any other class without an interface?

In a nutshell you'll either need to make a wrapper class yourself, or use a library that already provides wrapper classes for DateTime, like SystemWrapper.

like image 27
nas Avatar answered Oct 14 '22 07:10

nas


how would writing an IDateTimeProvider be reimplementing parts of the .Net Framework?

You'd just have two implementations, one that returns DateTime.Now and another that returns a value you specified before.

like image 34
Maxem Avatar answered Oct 14 '22 07:10

Maxem


An IDateTime provider might prove useful in other ways -- if your cache is to be used between client and server apps running on separate machines, you will one one single time-source for both machines (usually the server) otherwise the times may be out of step. I you use the IDateTimeProvider interface everywhere, then the client can use a version that gets the time from the server.

You would get that plus the Unit-testing de-coupling.

like image 39
Dr Herbie Avatar answered Oct 14 '22 07:10

Dr Herbie