We have a very massive system where reports are run off dates from specific days through to today's date using various definitions of "GenerateSalesReport(DateStart, Date.Now)".
For debugging purposes, I want to simulate repor开发者_开发问答ts that occurred in the past so I need to change the object "Date.Now" to a specific date from the past on my development environment. Is it possible to override date.Now
?
That is one of the failings of DateTime.Now
and related functions.
You should be passing in a DateTime
to any function that relies on it. Any place you use DateTime.Now
or DateTime.Today
(and such) is a place where you should be passing in the date.
This allows you to test for different DateTime
values, will make your code more testable and remove the temporal dependency.
A good solution is to abstract away external dependencies to be able to be able to stub them during test. To virtualize time I often use something like this:
public interface ITimeService {
DateTime Now { get; }
void Sleep(TimeSpan timeSpan);
}
In your case you don't need the Sleep
part since you only depend on the current time, and of course you need to modify your code to use an externally supplied ITimeService
when the current time is required.
Normally you would use this implementation:
public class TimeService : ITimeService {
public DateTime Now { get { return DateTime.Now; }
public void Sleep(TimeSpan timeSpan) { Thread.Sleep(timeSpan); }
}
For testing purposes you can instead use this stub:
public class TimeServiceStub : ITimeService {
public TimeServiceStub(DateTime startTime) { Now = startTime; }
public DateTime Now { get; private set; }
public void Sleep(TimeSpan timeSpan) { Now += timeSpan; }
}
Even if this were possible, you'd probably be better off changing the system time. Otherwise you've created a whole new test case (where your system is running under a different time than every other process on the system). Who knows what kind of problems you could run into.
精彩评论