views:

302

answers:

3

Hi,

In order to Unit-Test a feature, I need to fake DateTime.Now. Something like:

SupposeNowIs(new DateTime(..));

I can either use a third library that does it, or write my own little class. What do you recommand? Do you know any good library for this purpose? How would you fake time in C#? By changing DateTime.Now? (I suppose it's read only?).

Thank you!

+2  A: 

there are only 2 products that do this I think, one is the new one from Telerik, JustMock, and the other is TypeMock Isolator.

the Telerik on is quite new, but can also mock FileInfo and a couple of other class from the mscorlib.dll. They also say that they will be supporting more types in the future

as has been pointed out in other answers, the moles research project from Microsoft also does this

Sam Holder
+6  A: 

What you have is a hard dependency on "the current time". To make it simpler for you to fix this, you could separate out this to a "time service", which you could then mock away.

However, if you still wish to mock out DateTime.Now, look at the following products:

Of the three, I would go for TypeMock at the moment, Moles is a research project at Microsoft at the moment, and Just.Mock is still in beta.

Lasse V. Karlsen
Thanks. I'm taking a look at TypeMock Isolator. It appears that it does not just Mocking time but other things as well. So I'm a little bit sceptical because this isn't a personnal project I'm working on.
Amokrane
+11  A: 

Well, you can easily create your own injectable interface:

 public interface IClock
 {
     DateTime UtcNow { get; }
 }

 public class SystemClock : IClock
 {
     public DateTime UtcNow { get { return DateTime.UtcNow; } }
 }

 public class FakeClock : IClock
 {
     public DateTime UtcNow { get; set; }
 }

Inject that into your code as you would any other dependency. (I view both "give me the current time" and "give me a random number" as dependencies which should generally be injected just like anything else.)

All that being said, when Noda Time is production-ready, we will provide injectable clocks so you won't need to write your own :)

While you can mock this, I personally wouldn't... mocking is usually best for testing protocols where you care when dependencies are called and how often, etc. In this case you've got a "dumb" dependency, so effectively stubbing it is more appropriate... and that's more easily done with a concrete fake class. All IMO, of course.

Note that I've deliberately emphasized the UTC side of things... you can always call ToLocalTime() if you need to, but usually working in UTC is a better idea. In Noda Time the clock returns an Instant instead, but then we have a rather richer set of types to play with :)

Jon Skeet
Thanks for the ellaborate answer! But, I didn't really understand your first idea. How can this FakeClock fake time? In my situation, a task should be runned if this time is reached! I just can't see how this can help!
Amokrane
@Amokrane: You write your production code so that it can be provided an IClock to use whenever it needs to know the time (e.g. as a constructor or a property). For production use, you create a SystemClock (in whatever code creates the instance). For test use, you pass in a FakeClock.
Jon Skeet
Ok I got it. The production code will need to be changed a little bit (for the better I think). Because the schedule date wasn't implemented in the right Schedule class.Thank you for taking the time!
Amokrane