One of the principles of a unit test is that it must have full control of the system under test. This is problematic when production code includes calls to static methods, which cannot be changed or controlled. Date/time functions are usually provided by system libraries as static methods.

This can be improved by wrapping the system calls in an object or service that can be controlled inside the unit test.

Noncompliant Code Example

Public Class Foo
    Public Function HelloTime() As String
        Return $"Hello at {DateTime.UtcNow}"
    End Function
End Class

Compliant Solution

There are different approaches to solve this problem. One of them is suggested below. There are also open source libraries (such as NodaTime) which already implement an IClock interface and a FakeClock testing class.

Public Interface IClock
    Function UtcNow() As Date
End Interface

Public Class Foo
    Public Function HelloTime(clock As IClock) As String
        Return $"Hello at {clock.UtcNow()}"
    End Function
End Class

Public Class FooTest
    Public Class TestClock
        Implements IClock
        ' implement
    End Class

    <Fact>
    Public Sub HelloTime_Gives_CorrectTime()
        Dim dateTime = New DateTime(2017, 06, 11)
        Assert.Equal((New Foo()).HelloTime(New TestClock(dateTime)), $"Hello at {dateTime}")
    End Sub
End Class

Another possible solution is using an adaptable module, ideally supports an IDisposable method, that not only adjusts the time behaviour for the current thread only, but also for scope of the using.

Public Module Clock
    Public Function UtcNow() As Date
    End Function

    Public Function SetTimeForCurrentThread(time As Func(Of Date)) As IDisposable
    End Function
End Module

Public Class Foo
    Public Function HelloTime() As String
        Return $"Hello at {Clock.UtcNow()}"
    End Function
End Class

Public Class FooTest
    <Fact>
    Public Sub HelloTime_Gives_CorrectTime()
        Dim dateTime = New DateTime(2017, 06, 11)

        Using SetTimeForCurrentThread(Function() dateTime)
            Assert.Equal((New Foo()).HelloTime(), $"Hello at {dateTime}")
        End Using
    End Sub
End Class

See

NodaTime testing