Using .NET shims to unit test datetime method

I have to test a method that calculates the time difference of the local time and UTC. So I've tried to use a shims in order to change the local time and UTC but this does not work. Here is my unit test code:

<TestMethod()> Public Sub CurrentTimeTest()

    'Arrange
    Dim expected As System.DateTime
    expected = New DateTime(2015, 3, 5, 20, 0, 0)
    Dim actual As DateTime
    actual = DateTime.Now
    'Act
    Using (ShimsContext.Create())
        System.Fakes.ShimDateTime.NowGet = Function() As System.DateTime
                                               Return New DateTime(2015, 3, 5, 20, 0, 0)
                                           End Function

        System.Fakes.ShimDateTime.UtcNowGet = Function() As System.DateTime
                                               Return New DateTime(2015, 3, 5, 15, 0, 0)
                                           End Function
    End Using

    'Assert
    Assert.AreEqual(expected, actual)
End Sub

I cannot figure out why DateTime.Now is not equal to that I've set. Any help will be appreciated. Thanks in advance.

Jon Skeet
people
quotationmark

You're calling DateTime.Now before you set up the shim... so it can't possibly retroactively change the value of actual. I suspect if you use:

Dim actual As DateTime
'Act
Using (ShimsContext.Create())
    System.Fakes.ShimDateTime.NowGet = Function() As System.DateTime
            Return New DateTime(2015, 3, 5, 20, 0, 0)
        End Function

    System.Fakes.ShimDateTime.UtcNowGet = Function() As System.DateTime
            Return New DateTime(2015, 3, 5, 15, 0, 0)
        End Function
    actual = DateTime.Now
End Using

'Assert
Assert.AreEqual(expected, actual)

... then it'll work. But as noted in a comment, personally I would treat "I need the current time" as a dependency, and represent it in an interface (IClock). Then you can have different implementations for production and testing (or use mocks if you really want) just as you would for any other dependency.

people

See more on this question at Stackoverflow