I've tried to use XCTKeyPathExpectation in an async environment and could not get it to work. The error I'm getting is confusing me a lot. Because the error stated is not really an error in my opinion...
I've created a very simple test to see if I did something wrong. Using the following two classes:
TestMock.swift:
import Foundation
@testable import UnitTests
final class TestMock: NSObject {
@objc private(set) var testCalled: Bool = false
func test() {
self.testCalled = true
}
}
UnitTestsTests.swift:
import XCTest
@testable import UnitTests
final class UnitTestsTests: XCTestCase {
var testMock: TestMock!
override func setUpWithError() throws {
self.testMock = TestMock()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
self.testMock = nil
try super.tearDownWithError()
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
let expectation = XCTKeyPathExpectation(keyPath: \TestMock.testCalled,
observedObject: self.testMock,
expectedValue: true)
self.testMock.test()
self.wait(for: [expectation], timeout: 1.0)
}
}
It gives me the error: testExample(): Asynchronous wait failed: Exceeded timeout of 1 seconds, with unfulfilled expectations: "Expect value of 'Swift.ReferenceWritableKeyPath<UnitTestsTests.TestMock, Swift.Bool>' of <UnitTestsTests.TestMock: 0x600003bfc090> to be 'true', was 'true'".
The only thing I can think of is that is comparing a Swift.Bool with an Objective-C Bool. But not sure how to fix this.
It appears that I needed to add the word 'dynamic' to the declaration of testCalled.