A typical UnitTest establishes some known initial conditions (by creating objects with known values), executes a method with known parameters, and checks whether return values and side effects match expectations. But what happens when the method uses the system date and time?
Some Examples:
(Also see the VirtualClock test pattern.)
Some ways that the TestOverridesNow are ...
Objection: Having all your code call one "current time" function that you write does not violate OnceAndOnlyOnce, as the system's "current time" function does not implement the required "override the clock" testing functionality. So, implement a "system.localTimeNow" that returns a certain preset time in certain testing situations, or otherwise calls system.timeNow.
Note that the answers will change if the input (i.e. date) changes. Therefore don't change the input. Therefore don't override now. Have a method accountsOverdueOn: aDate and test that on a known date, thusly:
accountsOverdueOn: aDate ^accounts select: [ :each | each overdueOn: aDate] accountsOverdueToday ^self accountsOverdueOn: Date todayThe need to test accountsOverdueToday is, um, limited.
Tests that work with dates (and code in general) should almost never reference "now". Exceptions:
From: TestPrintedOutput
On the contrary. In most cases, to test with known values, the input dates must in fact NOT change.
Can you give an example of this?
Why not just pass in the test date as a parameter rather than getting the system date internally? This not only makes the routine easier to test but makes for a more general method as well.
If one must leave the system date internal to the method, then test by varying one's input date. One can test with System Date - 1 day, System Date, System Date + 1 day, etc.
Or change the system clock. What, you run tests as a limited user? HaHaOnlySerious
Two words: MOCK OBJECTS. That's what they were designed for. --SamuelFalvo?
Yes, MockObjects are your friends.