An injectable and testable clock.
If your code is not in a state where you can easily inject an IClock
(see: Using the injectable clock) you may find that the DateTime
extention methiod ShouldBeDuringTest(...)
is good enough to assert that a DateTime
object represents a time during the test run.
To use this technique, you must first add the Stravaig.Clock.Testing nuget package to your test project. Then you need to set up a TestClock
during the “arrange” phase of the test, and then assert the relevant DateTime
objects during the “assert” stage of the test.
e.g.
1
2
3
4
5
6
7
8
9
10
11
12
13
[Test]
public void TestTheThing()
{
// Arrange
var clock = TestClock.Start();
var thing = new Thing();
// Act
thing.DoStuff();
// Assert
thing.StuffHappenedAt.ShouldBeDuringTests(clock);
}
If the test fails the test running will show a message like this:
1
2
3
4
5
6
7
thing.StuffHappenedAt should be after the test started.
The time should be between
2023-08-12T13:58:55.8078350+01:00
and
2023-08-12T13:58:55.8089880+01:00
but was
2023-08-12T13:58:55.8066560+01:00
or
1
2
3
4
5
6
7
thing.StuffHappenedAt should be before the test ended.
The time should be between
2023-08-12T13:58:55.7799870+01:00
and
2023-08-12T13:58:55.7811500+01:00
but was
2023-08-12T13:58:55.7823020+01:00
The TestClock
will work out what to do if the time given is local or UTC, however, if the time being asserted is of DateTimeKind.Unspecfied
then you will need to specify a hint to the ShouldBeDuringTest()
method so it can interpret the date properly.
e.g.
1
thing.StuffHappenedAt.ShouldBeDuringTests(clock, DateTimeKind.Utc);
If you don’t specify the hint, then the test will fail with the message:
1
thing.StuffHappenedAt has an unspecified kind. Unable to interpret 2023-08-12T12:58:55.8322840 as UTC or Local.