본문 바로가기

iOS

[iOS] Mock 데이터 기반 TDD 적용하기 - OHHTTPStubs

반응형

현재 프로젝트는 API 프로토콜을 정의하고, 해당 구현체를 주입하는 방식으로 API를 사용하고 있습니다.

따라서 테스트를 위해 Mock API 구현체를 구현하고, 해당 객체를 주입하여 테스트를 할 수 있습니다.

하지만, 위와 같은 방식으로 하기에는 다소 까다로운 점들이 있습니다.

  1. 테스트하고자 하는 API 외에도 프로토콜 채택하기 위해 다른 API에 해당하는 function들도 구현해야 함

  2. Mock Object 주입을 위한 코드 수정이 불가피함

  3. 다양한 방식으로 테스트의 어려움 (ex) 비동기 테스트, 같은 API 성공/실패 혹은 다양한 값)

위와 같은 까다로움을 OHHTTPStubs를 통해 해소할 수 있다고 판단했습니다. OHHTTPStubs는 좀 더 Low level인 URLSessionConfiguration를 swizzling을 하여 테스트할 API를 호출하면 미리 설정한 응답 값

으로 내려오게 함으로써 테스트를 용이하게 할 수 있습니다.

[OHHTTPStubs - 적용]

stub

이 함수만 이해한다면, OHHTTPStubs를 사용하는데 무리가 없다고 생각합니다. (주로 이것만 사용함)

  • condition: 테스트를 진행할 request 여부 판단

  • response: 위의 request 정보에 해당하는 Mock Response 지정

1. condition

HTTPStubsTestBlock은 bool을 반환하며, NSURLRequest를 인자로 가진 블록입니다.

현재 request 중인 정보가 테스트할 정보인지 판단합니다.

 

사용 예시)

위와 같이 요청 중인 정보를 확인할 수 있지만, OHHTTPStubs/Swift에서 제공하는 방식을 이용하여 간결하게 표현할 수 있습니다.

 

OHHTTPStubs는 Objective-C 기반의 라이브러리이며, OHHTTPStubs/Swift는 이를 Swift 스럽게 사용할 수 있도록 래핑 되어 있는 것입니다. stub 함수도 stubRequestsPassingTest 함수를 래핑 한 형태로 OHHTTPStubs/Swift를 통해 사용할 수 있는 함수입니다.

2. response

HTTPStubsResponse를 반환하며, NSURLRequest을 인자로 가진 블록입니다.

condition에 해당하는 request일 경우 HTTPStubsResponse를 반환하여 해당 Response를 받을 수 있도록 합니다.

 

사용 예시)

위와 같이 테스트하고자 하는 jsonObject를 만들고 Response에 주입하여 해당 값을 받을 수 있습니다.

추가적으로 request 요청 시작 시간, response 받아오는 시간을 지정하여 다양한 환경에서 테스트를 진행할 수 있습니다.

 

header 값으로 nil이 들어가도 정상적으로 jsonObject를 테스트할 수 있는 이유는, jsonObject로 초기화 당시, 헤더에 Content-Type 이 누락되어 있다면 application/json 을 추가해주기 때문입니다.

 

주의 사항

stub 함수를 이용하여 테스트를 진행하는 경우, 해당 stub을 HTTPStubs의 싱글톤 객체의 stubDescriptors에 추가하게 됩니다. 따라서 테스트 진행을 완료한 이후에는 HTTPStubs.removeAllStubs()을 통해 진행한 stub들을 제거하는 것이 안전합니다.

 

추가하면 좋을 것?

1. HTTPStubsResponse jsonString 생성자

2. HTTPStubsResponseBlock 간편 생성 함수

샘플 테스트 코드

 

반응형