https://developer.apple.com/documentation/xctest/asynchronous_tests_and_expectations/testing_asynchronous_operations_with_expectations
위 링크를 보면 좋은 예제가 있다.
만일 네트워크 RESTFul API를 요청 하는 함수들 과
응답에 결과를 delegate로 호출 해주는 방법으로 만든 클래스가 있다면
이 class의 unit 테스트를 만들려면 testcase 함수 에서는 응답이 오기전에 XCAssertEqual()등의 메서드를 호출 할 수 없다. 네트워크 응답을 delegate로 받고 테스트가 진행 되어야 한다.
XCTest case 함수에서
XCTestExpectation 변수를 전역 변수로 만들고
테스트 케이스 함수에서 네트워크 요청 후
wait(for: [expectation], timeout: 10.0)
위와 같은 코드로 대기를 하게 한다.
XCAssertEqual() 메서드든 wait 코드 아래에 위치 하게 한다.
네트워크 클래스의 delegate 응답 결과를 처리 하는 protocol 메서드에서
expectation.fulfill() 을 호출 하여 대기를 풀어 준다.
그럼 wait이 풀리고 XCAssertEqual에서 테스트 판단이 이루어진다.
말로 설명한 TestCase 코드는 다음과 같다.
let expectation = XCTestExpectation(description: "Network API TEST")
func testLogin() {
// 1. given
// 2. when
network.login = Network.Login(aId: "choijh", aPassword: "1234567a")
network.request(API: Network.API.Login, delegate: self)
wait(for: [expectation], timeout: 10.0)
// 3. then
XCTAssertEqual( self.success, true, "Login success")
}
func testLoginFail() {
// 1. given
// 2. when
network.login = Network.Login(aId: "choijh", aPassword: "a")
network.request(API: Network.API.Login, delegate: self)
wait(for: [expectation], timeout: 10.0)
// 3. then
XCTAssertEqual( self.success, false, "Login fail wrong password")
}
func onReceiveSuccessFail(_ success: Bool, api: Network.API) {
self.success = success
expectation.fulfill()
}