취해야 할 접근법은 테스트 이중을 사용하여 upload
방법으로 올바른 네트워킹 호출이 이루어 졌는지 확인하는 것입니다. URLSession
일 수도 있고 AlamoFire와 같은 다른 라이브러리 일 수도있는 네트워킹 라이브러리에 대한 비동기 호출을 작성합니다. 어느 라이브러리가 사용 중인지에 관계없이 귀하의 upload
방법을 사용해야합니다.
이렇게하려면 URLSession을 직접 사용하지 말고 테스트에서 모의 할 수있는 인터페이스에 맞는 래퍼를 사용하고 싶습니다. 이는 코드가 테스트 시간보다 런타임에 네트워킹 클래스의 다른 구현을 사용한다는 것을 의미하며 필요에 따라 올바른 코드를 "주입"합니다.
예를 들어, 당신은 당신의 네트워킹 라이브러리에이 인터페이스를 할 수 : 다음 실제 구현
protocol NetworkRequesting {
func post(data: Data, url: URL)
}
실행시 사용되는 : 시험 시간에,
struct NetworkRequester: NetworkRequesting {
func post(data: Data, url: URL) {
let session = URLSession()
let task = session.uploadTask(with: URLRequest(url: url), from: data)
task.resume()
}
}
그러나, 사용 대신 다음과 같은 가짜 :
class MockNetworkRequester: NetworkRequesting {
var didCallPost = false
var spyPostData: Data? = nil
var spyPostUrl: URL? = nil
func post(data: Data, url: URL) {
didCallPost = true
spyPostData = data
spyPostUrl = url
}
}
그리고 다음 클래스 테스트 대상 :
class ImageUploader {
let networkRequester: NetworkRequesting
init(networkRequester: NetworkRequesting) {
self.networkRequester = networkRequester
}
func upload(image: UIImage, url: URL) {
}
}
당신은과 같이 upload
의 구현을 테스트 할 수 upload
는 아무것도하지 않는 것처럼
class UploadImageTests: XCTestCase {
func test_uploadCallsPost() {
let mockNetworkRequester = MockNetworkRequester()
let uploader = ImageUploader(networkRequester: mockNetworkRequester)
uploader.upload(image: UIImage(), url: URL(string:"http://example.com")!)
XCTAssert(mockNetworkRequester.didCallPost)
}
}
현재, 그 테스트가 실패합니다,하지만 당신은 넣을 경우 테스트중인 클래스에 다음, 테스트가 통과합니다 :
func upload(image: UIImage, url: URL) {
guard let otherUrl = URL(string:"https://example.org") else { return }
networkRequester.post(data: Data(), url: otherUrl)
}
그리고 이것이 첫 번째 TDD주기입니다. 분명히 원하는대로 동작하지 않으므로 사용 된 URL이 예상 한 URL인지 아니면 전달 된 데이터가 예상 한 것인지를 확인하기 위해 다른 테스트를 작성해야합니다.
런타임시 실제 네트워크 리퀘 스터를 사용하는 코드를 얻는 데는 여러 가지 방법이 있습니다. init 메소드가 기본 매개 변수 값을 사용하여 NetworkRequester
을 사용하게하거나 정적 팩토리 메소드를 사용하여 만들 수 있습니다. Inversion of Control과 같은 다른 옵션이 있습니다.이 옵션은이 답변의 범위를 훨씬 벗어납니다.
기억해야 할 중요한 점은 네트워킹 프레임 워크를 테스트하지 않고 네트워크 프레임 워크에 대한 올바른 호출을 테스트한다는 것입니다. 필자는 프로토콜 인터페이스를 매우 선언적으로 유지하여 모든 프레임 워크에서 요청을하기 위해 필요한 것들을 전달하지만, 여러분은 금속에 더 가까이 가서 URLSession의 구현을 미러링하는 것을 선호 할 것입니다. 이는 여러분에게 달려 있습니다. 제 생각에는 과학보다는 예술입니다.
나는 당신의 접근법을 좋아하는데, 나는 그것을 시도 할 것입니다. :) 저에게이 답을주기 위해 시간을내어 주셔서 감사합니다. – Helbo