Dalam artikel ini, kami akan menguji ViewModel kami di aplikasi Android sampel kami yang berisi logika untuk meminta detail karyawan menggunakan Retrofit. Kami memiliki dependensi berikut yang ditambahkan ke file build.gradle kami:
//for retrofit.
implementation 'com.squareup.retrofit2:retrofit:2.7.1'
implementation 'com.squareup.retrofit2:converter-gson:2.7.1'
implementation 'android.arch.lifecycle:extensions:1.1.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
//for testing retrofit.
testImplementation("com.squareup.okhttp3:mockwebserver:4.7.2")

ViewModel kami seperti ini:
class RequestViewModel : ViewModel() {
private val result = MutableLiveData<Resource<MainData>?>()
fun fetchDetails() {
val apiHelper = ApiHelperImpl(RetrofitBuilder.apiInterface)
apiHelper.getEmployeeDetails()
.enqueue(object : Callback<MainData> {
override fun onFailure(call: Call<MainData>, t: Throwable) {
result.postValue(Resource.error("Something went wrong!",null))
}
override fun onResponse(call: Call<MainData>, response: Response<MainData>) {
result.postValue(Resource.success(response.body()))
}
})
}
fun getDetail(): LiveData<Resource<MainData>?> {
return result
}
}
Jadi, untuk menguji ViewModel di atas, kita akan menggunakan MockWebServer of square. Pertama, kita mulai dengan mengatur respons .json yang diharapkan. Kami telah mengintegrasikan API berikut di aplikasi kami:
http://dummy.restapiexample.com/api/v1/employees
Jadi, kami menambahkan file .json berikut ke direktori sumber daya yang hanya berisi respons sukses dan gagal dari API di atas.

Pindah ke paket pengujian kami di mana kami benar-benar akan menulis pengujian unit untuk menguji RequestViewModel kami. Namun sebelum itu, kita harus menulis kode untuk membaca file.json di atas.
class MockResponseFileReader(path: String) {
val content: String
init {
val reader = InputStreamReader(this.javaClass.classLoader?.getResourceAsStream(path))
content = reader.readText()
reader.close()
}
}
Sekarang, mari buat pengujian RequestViewModelTest.kt untuk menguji logika Retrofit yang ada di kelas RequestViewModel. Dalam metode setUp() mari kita inisialisasi mockito, instance RequestViewModel, daftarkan pengamat kita dan hal-hal penting dari artikel ini, inisialisasi MockWebServer dan mulai yang sama. Dengan ini kami juga menginisialisasi ApiHelper sehingga kami benar-benar dapat mengambil detail karyawan:
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
viewModel = RequestViewModel()
viewModel.getDetail().observeForever(apiEmployeeObserver)
mockWebServer = MockWebServer()
mockWebServer.start()
apiHelper = ApiHelperImpl(RetrofitBuilder.apiInterface)
}
Mari kita buat pengujian pertama kita untuk memeriksa konten file success_response.json yang telah kita buat di atas, konten tidak boleh nol dan jika kita menjalankan yang berikut, itu telah berhasil dilewati:
@Test
fun `read sample success json file`(){
val reader = MockResponseFileReader("success_response.json")
assertNotNull(reader.content)
}
Dalam pengujian berikutnya, mari ambil detail karyawan dan periksa apakah kode respons '200' dari server cocok dengan kode respons yang ada di success_response.json yang merupakan respons yang diharapkan:
@Test
fun `fetch details and check response Code 200 returned`(){
// Assign
val response = MockResponse()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setBody(MockResponseFileReader("success_response.json").content)
mockWebServer.enqueue(response)
// Act
val actualResponse = apiHelper.getEmployeeDetails().execute()
// Assert
assertEquals(response.toString().contains("200"),actualResponse.code().toString().contains("200"))
}
Akhirnya, tes di atas telah lulus. Pada pengujian berikutnya, mari kita ambil status dari success_response.json dan bandingkan dengan status sebenarnya yang kita peroleh dari server:
@Test
fun `fetch details and check response success returned`(){
// Assign
val response = MockResponse()
.setResponseCode(HttpURLConnection.HTTP_OK)
.setBody(MockResponseFileReader("success_response.json").content)
mockWebServer.enqueue(response)
val mockResponse = response.getBody()?.readUtf8()
// Act
val actualResponse = apiHelper.getEmployeeDetails().execute()
// Assert
assertEquals(mockResponse?.let { `parse mocked JSON response`(it) }, actualResponse.body()?.status)
}
Jika Anda perhatikan di atas, kami memanggil satu metode bernama parse mocked JSON response
, yang pada dasarnya mem-parsing respons JSON yang ada di success_response.json.
Dan ya, tes di atas juga telah lulus, kami telah mendapat "keberhasilan" dari keduanya. Terakhir, jangan lupa untuk menghentikan MockWebServer dalam metode tearDown() dan membatalkan registrasi pengamat yang kita daftarkan dalam metode setUp():
@After
fun tearDown() {
viewModel.getDetail().removeObserver(apiEmployeeObserver)
mockWebServer.shutdown()
}