2

I am currently writing a test for a bug I've encountered, where the order of calls in the production code is incorrect, leading to a potential race condition.

What is the cleanest way to check the order of calls from the test code, using XCTest?

In OCMock/Objective-C we had setExpectationOrderMatters, as per this question. However I am not aware of similar functionality available in XCTest/Swift due to dynamic/static language differences.

Andrew Ebling
  • 10,175
  • 10
  • 58
  • 75

1 Answers1

1

Let's say we want to mock this protocol:

protocol Thing {
    func methodA()
    func methodB()
}

Here's a mock that doesn't just record call counts of individual methods. It records invocation order:

class MockThing: Thing {
    enum invocation {
        case methodA
        case methodB
    }
    private var invocations: [invocation] = []

    func methodA() {
        invocations.append(.methodA)
    }

    func methodB() {
        invocations.append(.methodB)
    }

    func verify(expectedInvocations: [invocation], file: StaticString = #file, line: UInt = #line) {
        if invocations != expectedInvocations {
            XCTFail("Expected \(expectedInvocations) but got \(invocations)", file: file, line: line)
        }
    }
}

This supports test assertions like:

mock.verify(expectedInvocations: [.methodA, .methodB])
Jon Reid
  • 20,545
  • 2
  • 64
  • 95