I have some unit tests that expects the 'current time' to be different than DateTime.Now and I don't want to change the computer's time, obviously.
What's the best strategy to achieve this?
I have some unit tests that expects the 'current time' to be different than DateTime.Now and I don't want to change the computer's time, obviously.
What's the best strategy to achieve this?
Good practice is, when DateTimeProvider implements IDisposable.
Next, you can inject your fake DateTime for unit tests
See example Example of DateTimeProvider
One special note on mocking
DateTime.Now
with TypeMock...The value of
DateTime.Now
must be placed into a variable for this to be mocked properly. For example:This does not work:
However, this does:
An alternative option that is not mentioned is to inject the current time to the dependent method:
The internal variation is open to unit testing, parallel or not.
This is based on the principle that
ImplicitTimeDependencyMethod
is "too simple to break" (see: http://junit.sourceforge.net/doc/faq/faq.htm#best_3) so does not need to be included in unit test coverage. Though it should be touched in integration tests anyway.Depending on the class' purpose it may be desirable to have both these methods public anyway.
These are all good answers, this is what I did on a different project:
Usage:
Get Today's REAL date Time
Instead of using DateTime.Now, you need to use
SystemTime.Now()
... It's not hard change but this solution might not be ideal for all projects.Time Traveling (Lets go 5 years in the future)
Get Our Fake "today" (will be 5 years from 'today')
Reset the date
I'm surprised no one has suggested one of the most obvious ways to go:
Then you can simply override this method in your test double.
I also kind of like injecting a
TimeProvider
class in some cases, but for others, this is more than enough. I'd probably favor theTimeProvider
version if you need to reuse this in several classes though.EDIT: For anyone interested, this is called adding a "seam" to your class, a point where you can hook in to it's behavior to modify it (for testing purposes or otherwise) without actually having to change the code in the class.
Add a fake assembly for System (right click on System reference=>Add fake assembly).
And write into your test method: