Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing in Retrofit for Callback

Here i got a sample of code in presenter. How do i make write a test for onSuccess and onFailure in retrofit call

public void getNotifications(final List<HashMap<String,Object>> notifications){

        if (!"".equalsIgnoreCase(userDB.getValueFromSqlite("email",1))) {
            UserNotifications userNotifications =
                    new UserNotifications(userDB.getValueFromSqlite("email",1),Integer.parseInt(userDB.getValueFromSqlite("userId",1).trim()));
            Call call = apiInterface.getNotifications(userNotifications);
            call.enqueue(new Callback() {
                @Override
                public void onResponse(Call call, Response response) {
                    UserNotifications userNotifications1 = (UserNotifications) response.body();


                    if(userNotifications1.getNotifications().isEmpty()){
                        view.setListToAdapter(notifications);
                        onFailure(call,new Throwable());
                    }
                    else {
                        for (UserNotifications.Datum datum:userNotifications1.getNotifications()) {
                            HashMap<String,Object> singleNotification= new HashMap<>();
                            singleNotification.put("notification",datum.getNotification());
                            singleNotification.put("date",datum.getDate());
                            notifications.add(singleNotification);
                        }
                        view.setListToAdapter(notifications);
                    }
                }

                @Override
                public void onFailure(Call call, Throwable t) {
                    call.cancel();
                }
            });
        }
    }

}

How do i write unittesting to cover all cases for this piece of code.

Thanks

like image 510
Jay Avatar asked Jul 18 '17 07:07

Jay


1 Answers

For those looking for an answer using Kotlin and MockK:

Assume you have something like this:

class ApiService(private val client: OkHttpClient) {
    
    fun makeApiCall() {
        val url = "https://someendpoint.com.br/"
        val request = Request.Builder().url(url).build()
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, exception: IOException) {
                //Logic to handle Failure
            }

            override fun onResponse(call: Call, response: Response) {
                //Logic to handle Success
            }
        })
    }
}

You can test this using Junit 5 and mockK

class ApiServiceTest {

    private lateinit var client: okhttp3.OkHttpClient
    private lateinit var apiService: ApiService

    @BeforeEach
    fun setup() {
        // Setup a new mock for each test case
        client = mockk(relaxed = true)
        apiService = ApiService(client)
    }

    @Test
    fun `test with mockedCallback`() {
        val mockedCall = mockk<Call>(relaxed = true) 

        every { mockedCall.enqueue(any()) } answers {
           //Get the callback from the arguments
            val callback = args[0] as Callback 
           // Create a fakeRequest 
           val fakeRequest =    okhttp3.Request.Builder().url("https://someendpoint.com.br/").build()
            // Create the response you need to test, it can be failure or success
            val errorResponse = Response.Builder()
                    .request(fakeRequest)
                    .protocol(Protocol.HTTP_1_1)
                    .code(400)
                    .message("Error")
                    .build()
            //Call the callback with the mocked response you created.
            callback.onResponse(mockedCall, errorResponse)
        }

        // Setup the client mock to return the mocked call you created
        every {
            client.newCall(any())
        } returns mockedCall

       apiService.makeApiCall()
       
       // Verify whatever you need to test your logic to handle each case.
    }

}
like image 176
manoellribeiro Avatar answered Sep 21 '22 03:09

manoellribeiro