I have a test where I'm using TaskLocal.withValue()
to configure reproducible testing environment.
I end up with code like this:
class MyTest: XCTestCase {
let testEnv = TestEnvironment()
func testZero() {
Environment.$current.withValue(testEnv) {
XCTAssertEqual(sut(value: 0), ...)
}
}
func testPositive() {
Environment.$current.withValue(testEnv) {
XCTAssertEqual(sut(value: +1), ...)
}
}
func testNegative() {
Environment.$current.withValue(testEnv) {
XCTAssertEqual(sut(value: +1), ...)
}
}
...
}
Which is a lot of boilerplate code. In theory, XCTestCase
provides methods setUp()
and tearDown()
which exist exactly as a home for common preparation code before and after test.
But in this case, I cannot use them, because TaskLocal
does not provide two separate methods for setup and teardown, for good reasons.
So, I think this should be addressed on the side of the XCTest
. There should be a customisation point that allows extracting common setup/teardown code using single method that takes a closure as a parameter. Something like this:
class MyTest: XCTestCase {
override func withEnvironment(_ test: () -> Void) {
let testEnv = TestEnvironment()
Environment.$current.withValue(testEnv) {
super.withEnvironment(test)
}
}
func testZero() {
XCTAssertEqual(sut(value: 0), ...)
}
func testPositive() {
XCTAssertEqual(sut(value: +1), ...)
}
func testNegative() {
XCTAssertEqual(sut(value: +1), ...)
}
...
}