[swift] 프로토콜을 활용한 모의 객체 생성 (Mocking)

테스트 주도 개발(TDD)을 수행할 때, 종속 항목을 테스트하는 경우에 모의 객체(Mock Object)를 생성하는 것이 중요합니다. 모의 객체는 테스트 대상 객체와의 상호작용을 시뮬레이션하여 테스트를 보다 효과적으로 수행할 수 있도록 도와줍니다.

모의 객체를 만들기 위해 프로토콜을 이용하는 방법에 대해 알아보겠습니다.

프로토콜 정의

먼저, 모의 객체를 만들기 위한 프로토콜을 정의합니다. 다음은 NetworkService 프로토콜의 예시입니다.

protocol NetworkService {
    func fetch(completion: @escaping (Result<Data, Error>) -> Void)
}

모의 객체 생성

프로토콜을 준수하는 모의 객체를 생성하기 위해, MockingbirdSourcery 같은 코드 생성 도구를 활용할 수 있습니다.

// Mockingbird를 사용한 모의 객체 생성 예시
import Mockingbird

let mockNetworkService = mock(NetworkService.self)
given(mockNetworkService.fetch(completion: any())).willComplete(with: .success(Data()))

위의 예시에서,Mockingbird를 사용하여 NetworkService 프로토콜을 준수하는 모의 객체를 생성하고, fetch 메서드를 특정 결과로 설정하고 있습니다.

테스트 케이스에서 활용

테스트 케이스에서는 생성된 모의 객체를 주입하여 테스트를 수행할 수 있습니다.

class MyNetworkClient {
    let networkService: NetworkService

    init(networkService: NetworkService) {
        self.networkService = networkService
    }

    func fetchData() {
        networkService.fetch { result in
            // Do something with result
        }
    }
}

// 테스트 케이스
class MyNetworkClientTests: XCTestCase {
    func testFetchData() {
        let mockNetworkService = mock(NetworkService.self)
        let myNetworkClient = MyNetworkClient(networkService: mockNetworkService)
        // Test the fetchData method
    }
}

위의 예시에서, MyNetworkClient 클래스의 테스트에서 NetworkService 프로토콜을 준수하는 모의 객체를 만들어서 테스트에 활용하고 있습니다.

프로토콜과 모의 객체를 활용하여 테스트 가능한 코드를 작성함으로써, 더 견고하고 유지보수가 용이한 애플리케이션을 구축할 수 있습니다.