Summary#
Without it, a test reads the real clock (or, forked from a fixture, the moment its fixture was seeded — see TestClock.Advance and TestClock.Set). That is right for most suites, and it is why pinning is opt-in: turning it on changes what every existing test reads as "now". A project whose tests reason about dates — a booking for tomorrow, a monthly report, a reminder at nine — opts in once:
app.TestClock = new DateTime(2030, 1, 15, 9, 30, 0); // in any .test.osy — read as UTCThen DateTime.UtcNow in every test body, in every fixture, in a query's Where(…), on the page a test opens and in
the server call a click makes all read 15 January 2030, 09:30 — on every machine, on every day.
Signature#
app.TestClock = new DateTime(<year>, <month>, <day>);
app.TestClock = new DateTime(<year>, <month>, <day>, <hour>, <minute>, <second>);Description#
- Per project. Write it once, in any one of the files your
testsglob collects; it applies to every test file. - Pinned, not running. The clock stands at that instant until a test moves it —
TestClock.Advance(…)steps it on,TestClock.Set(…)puts it somewhere else. A fixture that moves it hands its tests the instant it left it at. - Fixtures start there too. A row a
[TestFixture]stamps withDateTime.UtcNowholds the pinned instant, so a test forked from it reads a world built at the same moment it reads as "now". - In a
.test.osyonly. In a model file it would pin nothing, so it is refused there. Outsideosy testit does nothing at all: a running app reads the real clock (andosy clockmoves a running local app's clock — see Moving the running app's clock). - Written out. Year, month and day, then optionally hour, minute and second, as number literals, read as UTC. It is read before anything runs, so it cannot be computed.
app.TestClock = new DateTime(2030, 1, 15, 9, 30, 0);
[Test]
void now_is_the_projects_instant() {
Assert.Equal(new DateTime(2030, 1, 15, 9, 30, 0), DateTime.UtcNow);
}
[Test]
void a_test_still_moves_it_on() {
TestClock.Advance(TimeSpan.FromHours(2));
Assert.Equal(new DateTime(2030, 1, 15, 11, 30, 0), DateTime.UtcNow);
}See also#
- TestClock.Advance and TestClock.Set —
TestClock.SetandTestClock.Advance, and every clock they move - Fixtures: built once, cloned for every test, and built on each other — what a test forked from a fixture starts from
- Moving the running app's clock — moving a running local app's clock with
osy clock