Testing Time with MutableClock
When working with dates or time we often have the problem of writing stable tests.
Java only provides a FixedClock
for testing.
However, often time related code has to deal with the change of time,
so a fixed clock is not enough or makes the test harder to follow.
The prerequisite for using both FixedClock
and Spocks MutableClock
is that the production code,
actually uses a configurable Clock
and not just the parameterless Instant.now()
or the corresponding methods in the other java.time.*
classes.
Example
Class under Test
|
1 | Clock is injected via constructor |
2 | Clock is used to get the current date |
Test
|
1 | MutableClock created with a well known time |
2 | Clock is injected via constructor |
3 | age is less than 18 so the result is false |
4 | the clock is advanced by one day |
5 | age is equal to 18 so the result is true |
There are many more ways to modify MutableClock
just have a look at the JavaDocs, or the test code spock.util.time.MutableClockSpec
.
Collection Conditions
Sometimes, you want to assert the elements of a collection regardless of their order.
The Groovy way to do this is to cast both to Set
, i.e. x as Set == [1, 2, 3] as Set
.
While this works, it is very noisy.
Since Spock 2.1 you can use two new conditions:
-
x =~ [1, 2, 3]
is a lenient match, i.e., checking that x contains at least one instance of every item in the list (same semantics as casting both toSet
before comparing). -
x ==~ [1, 2, 3, 3]
is a strict match, i.e., checking that x contains exactly the items in the list regardless of their order (using Hamcrest’scontainsInAnyOrder
under the hood).
Lenient Match
|
|
Strict Match
|
|
Both operands must either be Iterable or an array for this to work.
Otherwise, it will be treated like the standard groovy find operator or match operators.
|
Interact with the file system using FileSystemFixture
In integration tests you often have to prepare the file system for a test.
For trivial cases like creating a single temp directory, you can use the @TempDir extension directly.
However, for more complex cases like creating a directory tree FileSystemFixture
offers convenience and better readability.
Examples
Creating a directory tree
|
To get the nice Groovy methods for Path , you need to add a dependency on groovy-nio .
|
Capture Values for Assertions with old()
It can be helpful to know the old value of an expression before the when:
was executed.
This allows you to compare the changes made by a when:
block.
You can capture the old value of an expression with old(<expr>)
in a then:
block,
which will return the value of the <expr>
before the previous when:
block is executed.
The usage of the old()
method makes a test less fragile, because you can assert the difference,
which was made by the when:
block.
Example
Using
old() to capture the old value of x
|