Retrofit2 MockServer test case 작성
2023. 4. 27. 18:02ㆍandroid
이번 포스트에서는 Retrofit2를 가지고 RESTful Api 이용시 어떻게 test 하는지 알아보는 시간을 가져보겠습니다. 무조건 이 방법이 맞는건 절대! 아닙니다. 저도 검색하고 적용하는 시행착오를 통해 하나의 방법을 알게되어 소개해드립니다. Retrofit2를 이용하는 방식과 구조 과정은 이해하고 있다는 전제 하에 진행하겠습니다.
Dependency (retrofit2는 있다고 전제 하에 추가한 dependency입니다.)
//coroutine Testing
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
//mock server
testImplementation 'com.squareup.okhttp3:mockwebserver:4.10.0'
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:4.10.0'
//junit4 testing
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
//core Testing
androidTestImplementation 'androidx.test:core:1.5.0'
전체 테스트 코드
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class Retrofit2Test {
private lateinit var server: MockWebServer
private lateinit var weatherApi: WeatherApi
private lateinit var retrofit: Retrofit
/*
SetUP함수
server는 mock 웹서버 인스턴스로 초기화합니다.
server.start()
start()함수는 주어진 port에 맞는 loopback interface 서버를 실행시킵니다.
(loopback interface란 실제로는 존재하지 않는 인터페이스)
retrofit을 만들어줍니다. url설정은 server의 url을 "/"로 간단하게 가상의 url을 설정합니다.
api는 실제로 서비스 인터페이스로 만들어둔 api를 retrofit을 이용해 api의 엔드포인트의 구현체를 생성합니다.
*/
@Before
fun setUp() {
server = MockWebServer()
server.start()
retrofit = Retrofit.Builder()
.baseUrl(server.url("/"))
.addConverterFactory(GsonConverterFactory.create())
.build()
weatherApi = retrofit.create(WeatherApi::class.java)
}
@After
fun tearDown(){
server.shutdown()
}
/*
test함수
response는 테스트했을 때 받을 값입니다. json 형태로 들어옵니다.
*/
@Test
fun getCurrentWeatherTest() = runTest {
val response = """
{
"response": {
"header": {
"resultCode": 0,
"resultMsg": "성공"
},
"body": {
"dataType": "JSON",
"items": {
"item": [
{
"baseDate": "20230426",
"baseTime": "0500",
"category": "T1H",
"fcstDate": "20230426",
"fcstTime": "0600",
"fcstValue": "10",
"nx": 60,
"ny": 127
}
]
}
}
}
}
""".trimIndent()
server.enqueue(MockResponse().setBody(response))
val weather = weatherApi.getCurrentWeather(
baseDate = "20230426",
baseTime = "0630",
nx = 55,
ny = 127
)
assertNotNull(weather)
assertEquals(weather.response.header.resultCode, 0)
assertEquals("성공", weather.response.header.resultMsg)
assertEquals("JSON", weather.response.body.dataType)
assertNotNull(weather.response.body.items.item)
}
}
각 함수에 주석을 달아서 설명을 첨부하였습니다.
@Before
setUp 함수에서 테스트 전 준비를 위해 초기화를 진행합니다.
api 같은 경우는 실제 날씨( 구 동네예보) 공공데이터 api를 받아오기 때문에 그에 맞춰서 작성해줬습니다.
API
interface WeatherApi {
@GET("getVilageFcst?serviceKey=${Constants.API_KEY}")
suspend fun getTodayWeather(
@Query("dataType") dataType : String = "json",
@Query("numOfRows") numOfRows : Int = 60,
@Query("pageNo") pageNo : Int = 1,
@Query("base_date") baseDate : String,
@Query("base_time") baseTime : String,
@Query("nx") nx : Int,
@Query("ny") ny : Int
) : Weather
@GET("getUltraSrtFcst?serviceKey=${Constants.API_KEY}")
suspend fun getCurrentWeather(
@Query("dataType") dataType: String = "json",
@Query("numOfRows") numOfRows: Int = 580,
@Query("pageNo") pageNo: Int = 1,
@Query("base_date") baseDate: String,
@Query("base_time") baseTime: String,
@Query("nx") nx: Int,
@Query("ny") ny: Int
): Weather
}
위와 같이 작성하였구요. 그래서 @Test함수의 weather 변수에 api를 통해 데이터를 받아옵니다. 먼저 하나의 api 함수만 테스트 해보았습니다. Test 함수 안에 보시면 아래와 같이 적혀있습니다. weather는 api에 함수를 실행시킨것 입니다.
val weather = weatherApi.getCurrentWeather(
baseDate = "20230426",
baseTime = "0630",
nx = 55,
ny = 127
)
assertNotNull(weather)
assertEquals(weather.response.header.resultCode, 0)
assertEquals("성공", weather.response.header.resultMsg)
assertEquals("JSON", weather.response.body.dataType)
assertNotNull(weather.response.body.items.item)
assertNotNull 은 null인지 아닌지 테스트하고
제대로 나오는지 확인을 위한 테스트가 또 그 밑으로 여러개 있습니다.
이런 식으로 테스트를 통해 Retrofit2의 api 가 제대로 작동하는지 확인해보았습니다.
여기에 있제 Repository 테스트를 하고 viewmodel test를 하면 됩니다.
이상으로 retrofit2 test에 대한 글을 읽어주셔서 감사하고 틀린 부분은 지적해주시면 감사하겠습니다~
'android' 카테고리의 다른 글
android context란 무엇인가? (0) | 2023.05.28 |
---|---|
android contentProvider를 이용하여 공유 저장소 미디어 파일에 엑세스 하는 방법을 통한 예시와 공홈 번역 및 공부 (0) | 2023.05.27 |
JUnit4를 이용한 Room DabaBase Test (0) | 2023.04.23 |
JUnit4를 사용한 Viewmodel , usecase , repository 패턴 Unit Test (0) | 2023.04.21 |
한 번의 글로는 이해가 안 가는 안드로이드 테스트 ( 유닛 테스트 & 계측 테스트 ) (0) | 2023.04.21 |