## Why is this an issue?

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

## Resources

NodaTime testing