본 포스팅은 Elye의 Android Mock Server for UnitTest를 번역하여 작성하였습니다.
(원어 부제: Make unit test for network fetching easier)
오늘날 우리가 구축하는 거의 모든 앱은 서버에서 무언가를 가져온다. 다양한 서비스 조건을 흉내낼 수 있는 모의 페이로드 혹은 더 나은 모의 서버로 로직을 단위테스트 할 수 있다면 얼마나 좋을까. 이것에 대한 좋은 소식으로는, OkHttp 라이브러리를 제공한 Square에서도 그들의 OkHttp를 위한 MockWebServer를 가지고 있다는 점이다.
설정
라이브러리 의존성
분명히 말하지만, 이것을 사용하려면 이미 OkHttp를 사용하고 있어야 한다.(이는 Retrofit을 사용하는 경우도 적용된다.) 그런 다음 앱의 build.gradle 파일에 Mock Web Server 라이브러리를 추가하기만 하면 된다.
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.3.1'
Mock Server 인스턴스화
아래는 var server = MockWebServer()로 인스턴스화 하는 방법이다. 그리고 시작할 때 server.start()를 하고, 끝날 때는 server.shutdown()를 하면 된다.
가져오는 것(fetching)을 수행하는 Chat 클래스가 있다고 가정하면, 아래에서 보여주는 것처럼 서버의 url을 설정하여 baseUrl을 얻어올 필요가 있다.
private var server = MockWebServer()
private lateinit var chat: Chat
@Before
fun setup() {
server.start(port)
val baseUrl: HttpUrl = server.url(path)
chat = Chat(baseUrl)
}
@After
fun tearDown() {
server.shutdown()
}
이제 당신은 여러 가능한 웹 서비스들의 응답을 테스트 할 준비가 되었다.
모의 웹 서비스
Body와 함께 모의 성공 응답
이것은 당신이 좋아하는 형태의 Body를 제공하는 가장 일반적인 것이다.
server.enqueue(MockResponse().setBody("{ result: \"success\" }")
만약 당신이 JSON 파일 결과로부터 body를 얻어오는 것을 좋아한다면, 아래의 글을 확인해보라.
Android Reading a Text File during Test
모의 응답 헤더
만약 당신이 헤더를 다시 받으려면 아래와 같이 추가하라.
val response = MockResponse()
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("Cache-Control", "no-cache"))
server.enqueue(response)
팁: 쿠키를 설정하는 방법으로는, 헤더를 통해서 할 수 있다.
val response = MockResponse()
.addHeader("Cookie", "cookie1=some-value; cookie2=other-value"))
server.enqueue(response)
모의 여러 응답들
때때로 당신은 다른 응답들을 테스트 하기 원한다.(같은 URL로부터 가져오는 경우에) 그땐 당신은 set이나 enqueue 응답을 제공할 수 있다.
server.enqueue(MockResponse().setBody("first result"))
server.enqueue(MockResponse().setBody("second result"))
server.enqueue(MockResponse().setBody("final result"))
조건부적인 응답과 함께 모의 설정
당신이 서버에 호출할 때 다른 경로를 가정하면, 다르게 응답할 것이다. 그것은 디스패처를 사용하는 것으로 모의처리가 가능하다.
val dispatcher: Dispatcher = object : Dispatcher() {
override fun dispatch(request: RecordedRequest): MockResponse {
when (request.path) {
"/v1/path1"
-> return MockResponse().setResponseCode(204)
"/v1/path2"
-> return MockResponse().setResponseCode(200)
.setBody("good")
}
return MockResponse().setResponseCode(404)
}
}
server.dispatcher = dispatcher
웹 서비스 에러 모의 설정
당신이 원하는 모든 서버 응답 코드를 모의로 할 수 있다.(가령, 300, 400, 404, 500 등) 당신이 필요한 모든 것에 대해서.
server.enqueue(MockResponse().setResponseCode(code))
더 느린 서비스를 모의 설정
당신은 타임아웃 핸들링을 포착하기위해 서비스의 속도를 늦을 수 있다.
server.enqueue(MockResponse().throttleBody(
bytesPerPeriod = 1, period = 2, unit = TimeUnit.SECONDS)
요청 포착하기
서버에 대한 요청을 포착하기 위해, 제공된 takeRequest API를 사용할 수 있다.
val request: RecordedRequest = server.takeRequest()
assertEquals(expectedPath, request.path)
assertNotNull(request.getHeader("Authorization"))
여러개의 후속 요청에 대해 처리하게 할 수도 있다.
val request1: RecordedRequest = server.takeRequest()
assertEquals(path1, request1.path)
val request2: RecordedRequest = server.takeRequest()
assertEquals(path2, request2.path)
당신은 이 곳에서 예제 코드를 얻을 수 있다.
그리고 자신의 JSON Response를 작성하는 것이 귀찮아 지는 경우, 아래를 참고해 보아라.
Instrumental Test: Record and reply your network payload
'[Developer] > Android' 카테고리의 다른 글
Android Dumpstate 로그 추출 및 분석(1/2) (2) | 2021.07.12 |
---|---|
[개발 팁] adb 디버깅 무선 연결하기 - Android 11 이상 (6) | 2021.04.26 |
Android Studio 3.5 주요 변화점 (0) | 2019.08.21 |
[트러블슈팅] Default file proguard-android.txt should not be specified in this module (0) | 2018.11.29 |
설치된 앱이 어느 마켓에서 설치되었는지 알아내기 (0) | 2018.06.25 |
댓글