I am looking for an alternative to Microsoft Fakes in .NET Core. I know it is no longer supported in .NET Core. I just do not understand why not, I think it was a good solution in certain situations.
My problem is that I want to mock DateTime.Now. Previously you could do this with the following code:
System.Fakes.ShimDateTime.NowGet = () =>
{
return new DateTime(2000, 1, 1);
};
It is described in the Microsoft documentation, see the link for more information: https://docs.microsoft.com/en-us/visualstudio/test/using-shims-to-isolate-your-application-from-other-assemblies-for-unit-testing?view=vs-2017
For now I solved it by creating a wrapper for DateTime, which looks like this:
/// <summary>
/// Used for getting DateTime.Now(), time is changeable for unit testing
/// </summary>
public static class SystemTime
{
/// <summary>
/// Normally this is a pass-through to DateTime.Now, but it can be
/// overridden with SetDateTime( .. ) for testing or debugging.
/// </summary>
public static Func<DateTime> Now = () => DateTime.Now;
/// <summary>
/// Set time to return when SystemTime.Now() is called.
/// </summary>
public static void SetDateTime(DateTime dateTimeNow)
{
Now = () => dateTimeNow;
}
/// <summary>
/// Resets SystemTime.Now() to return DateTime.Now.
/// </summary>
public static void ResetDateTime()
{
Now = () => DateTime.Now;
}
}
I owe this solution to the next StackOverflow post: Unit Testing: DateTime.Now
But I am not satisfied with this solution yet, because I feel I have to adjust my implementation for my testing. I do not think this is desirable.
I hope someone can help me with this, thanks in advance for the effort.
Pose works well for this.
using Pose;
Shim dateTimeShim = Shim.Replace(() => DateTime.Now).With(() => new DateTime(2004, 4, 4));
// This block executes immediately
PoseContext.Isolate(() =>
{
// All code that executes within this block
// is isolated and shimmed methods are replaced
// Outputs "4/4/04 12:00:00 AM"
Console.WriteLine(DateTime.Now);
}, dateTimeShim);