
Concurrency-Safe Testing in Swift 6.1 with @TaskLocal and Test Scoping
Today’s example shows a static property providing the current date. Perfect mechanism when we don’t want to inject it everywhere where it’s used. How to test it? Check it out ⤵️ Initial setup let currentDateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateStyle = .short formatter.timeStyle = .none return formatter }() var currentDateFormatted: String { currentDateFormatter.string(from: DateEnvironment.currentDate()) } enum DateEnvironment { static var currentDate: () -> Date = Date.init } extension Date { // 16.04.2025 static let sixteenthOfApril = Date(timeIntervalSince1970: 1744840515) } Old way - XCTest Override the static property in tests. Works, but not concurrency-safe (Ok, for XCTest because test ran serially). class CurrentDateFormatterTests: XCTestCase { func test_dateFormatting() { // ✅ DateEnvironment.currentDate = { .sixteenthOfApril } XCTAssertEqual(currentDateFormatted, "16.04.2025") } } Swift Testing before Swift 6.1 enum DateEnvironment { @TaskLocal static var currentDate: () -> Date = Date.init } struct CurrentDateFormatterTests { @Test func dateFormatting() { // ✅ DateEnvironment.$currentDate .withValue({ .sixteenthOfApril }) { #expect(currentDateFormatted == "16.04.2025") } } } Why @TaskLocal? ...