completionHandler를 포함하는 makeRandomValue(completionHandler:)와 reset(completionHandler:)를 테스트

✐ makeRandomValue(completionHandler:)

func makeRandomValue(completionHandler: @escaping () -> Void) {
    let urlString = "<http://www.randomnumberapi.com/api/v1.0/random?min=0&max=30&count=1>"
    guard let url = URL(string: urlString) else {
        return
    }

    let task = urlSession.dataTask(with: url) { data, response, error in
        guard let response = response as? HTTPURLResponse, (200...399).contains(response.statusCode) else {
            return
        }

        guard let data = data, error == nil else {
            return
        }

        do {
            guard let newValue = try JSONDecoder().decode([Int].self, from: data).first else {
                return
            }

            self.randomValue = newValue
            completionHandler()
        } catch {
            return
        }
    }

    task.resume()
}

func test_makeRandomValue호출시_randomValue를_0에서30까지숫자로설정해주는지() {
    // given
    sut.randomValue = 50 // 기본값이 0~30에 포함되면 무조건 테스트에 통과하므로 범위에서 벗어난 값을 할당

    // when
    sut.makeRandomValue {
        // then
        XCTAssertGreaterThanOrEqual(self.sut.randomValue, 0)
        XCTAssertLessThanOrEqual(self.sut.randomValue, 30)
    }
}

https://user-images.githubusercontent.com/73867548/131937969-36754666-e346-4e19-a5b6-e7c8bdc426a8.jpg

https://user-images.githubusercontent.com/73867548/131938361-851963b5-51b2-4eed-a553-bdc6e5e26421.jpg

✐ 비동기 메서드 테스트하기

func test_makeRandomValue호출시_randomValue를_잘설정해주는지() {
    // given
    let promise = expectation(description: "It makes random value") // expectation
    sut.randomValue = 50 // 기본값이 0~30에 포함되면 무조건 테스트에 통과하므로 범위에서 벗어난 값을 할당

    // when
    sut.makeRandomValue {
        // then
        XCTAssertGreaterThanOrEqual(self.sut.randomValue, 0)
        XCTAssertLessThanOrEqual(self.sut.randomValue, 30)
        promise.fulfill() // fulfill
    }

    wait(for: [promise], timeout: 10) // wait
}

🤔 timeout은 무엇인가요?

timeout은 비동기 작업을 기다리는 제한 시간같은 것입니다. 만약 비동기 메서드를 기다린다고는 했지만 비동기 메서드가 끝없이 동작하고 있다면 테스트는 진행되지가 않겠지요? 이를 방지하기 위해서 제한을 두는 것입니다. timeout은 Double 타입인 TimeInterval 값을 전달받습니다.

✐ reset(completionHandler:)