How to mock certain classes with Swift Testing?

Hi! If you search the Swift forums, you'll see a number of posts about mocking in Swift. :smile: Because Swift is statically typed, mocking as a general concept isn't really supported for value types. Date (from Foundation) is a value type, meaning it's basically just bits in memory—there's no place to put hooks for injecting test-time code.

We generally recommend using protocols for behaviour that may be dynamically selected at runtime. For instance, let's say you wanted to mock Date's timeIntervalSince1970 property. You could create a protocol with this member, add conformance to Date, add conformance to your mock type, and then have your business logic accept an instance of T: TheProtocol instead of just Date:

protocol HasTimeIntervalSince1970 {
  var timeIntervalSince1970: TimeInterval { get }
}

extension Date: HasTimeIntervalSince1970 {}

struct MockDate: HasTimeIntervalSince1970 {
  var timeIntervalSince1970: TimeInterval
}

func doSomeWork(with date: some HasTimeIntervalSince1970) -> Bool {
  if date.timeIntervalSince1970 < YEAR_2024 {
    print("It's the wrong year!")
    return false
  }
  // ...
  return true
}

@Test func testSomeWork() {
  let mockDate = MockDate(timeIntervalSince1970: ...)
  #expect(doSomeWork(with: mockDate))
}