Unittests mit aktueller Zeit
In einigen Anwendungsfällen muss System.DateTime.Now verwendet werden (siehe auch https://enterprisecraftsmanship.com/posts/domain-model-purity-current-time/). Dies ist bei einigen Unittests unhandlich oder Unittests können sogar gar nicht geschrieben werden. Dieses Muster beschreibt, wie dies einfach implementiert werden kann.
Design
Das Design wird anhand der Implementierung erläutert.
Implementierung
[Test] public void Now_ShouldReturnDateTimeNow() { IDateTimeOffsetProvider testObject = new DateTimeOffsetProvider(); DateTimeOffset testResult = testObject.Now; DateTimeOffset now = DateTimeOffset.Now; Assert.That(testResult, Is.EqualTo(now)); } [Test] public void Now_MockedShouldReturnSpecificDateTime() { Mock<IDateTimeOffsetProvider> dateTimeProviderStub = new Mock<IDateTimeOffsetProvider>(); dateTimeProviderStub.SetupGet(x => x.Now).Returns(new DateTimeOffset(2021, 1, 1, 1, 1, 1, TimeSpan.FromSeconds(0))); IDateTimeOffsetProvider demoObj = dateTimeProviderStub.Object; DateTimeOffset testResult = demoObj.Now; DateTimeOffset now = new DateTimeOffset(2021, 1, 1, 1, 1, 1, TimeSpan.FromSeconds(0)); Assert.That(testResult, Is.EqualTo(now)); }
Die Schnittstelle IDateTimeOffsetProvider
liefert also das aktuelle Datum. Die Standard und im produktiven Betrieb zu nutzende Klasse ist entsprechend DateTimeOffsetProvider
.
Nuztzungsszenarien
- Per DI den
IDateTimeOffsetProvider
undDateTimeOffsetProvider
injiziieren - im Normalfall im Usecase Controller - Von Hand in der Domäne nutzen
Abgrenzung
Die Lösung bezieht sich aktuell nur auf DateTimeOffset.Now
.
Stärken und Schwächen
Stärken
- Einfache Verwendung