Android: Network Calling with Retrofit and Unit Testing
How to Unit Test Network Calling in Android with the power of Retrofit
If get to know something new by reading my articles, don't forget to endorse me on LinkedIn
What is Retrofit?
Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.
Detail about Retrofit & How it works
What is Unit Testing?
Unit Testing is a type of software testing where individual units or components of a software are tested. The purpose is to validate that each unit of the software code performs as expected. Unit Testing is done during the development (coding phase) of an application by the developers. Unit Tests isolate a section of code and verify its correctness. A unit may be an individual function, method, procedure, module, or object.
What will be our Acheivement?
We want to acheive some basic testing for this article.
First, we will have an instance of Retrofit object which contain a valid BASE_URL and in Test, we will make sure that the BASE_URL Retrofit has, is same as our's BASE_URL
Second, we will create
Endpoint
andService
class for Retrofit, and we will test our First API Calling with Retrofit. In the Test, we will verify that API Execution return Success result.
Let's get into the coding part
First, let's create our Client Class
that provide an instance of Retrofit Object
with a valid BASE_URL
class RetrofitClient {
val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(MoshiConverterFactory.create())
.build()
}
}
When we call RetrofitClient().retrofit
provider return an lazy instance of Retrofit
.
Now, let's have our FIRST test of the Retrofit
instance. We will check if the provided Retrofit
instance have a BASE_URL that matches to our BASE_URL.
First Unit Test
For this test, Create a new Class
called RetrofitClientTest
under the test
package.
class RetrofitClientTest {
@Test
fun testRetrofitInstance() {
//Get an instance of Retrofit
val instance: Retrofit = RetrofitClient().retrofit
//Assert that, Retrofit's base url matches to our BASE_URL
assert(instance.baseUrl().url().toString() == BuildConfig.BASE_URL)
}
}
and, run the test.
✔️ Tests passed: 1 of 1 test - 438ms
BUILD SUCCESSFUL in 15s
28 actionable tasks: 16 executed, 12 up-to-date
8:02:23 PM: Tasks execution finished ':app:cleanTestDebugUnitTest :app:testDebugUnitTest --tests "com.rommansabbir.testing.RetrofitClientTest.testRetrofitInstance"'.
Fun, Right?.
Yeeeeee, we have our first Unit Test of Retrofit which verify that, the given instance of Retrofit contain a base url that exactly matches to our BASE_URL.
Now, Let's get into the API Testing part and we are creating our FIRST API Endpoint called PlacesEndpoint
and it's implementation PlacesService
.
interface PlacesEndpoint {
@Headers("Authorization: ${BuildConfig.API_KEY}")
@GET("places/nearby")
fun getVenueRecommendations(@QueryMap query: Map<String, String>): Call<ResponseWrapper>
}
class PlacesService constructor(private val retrofit: Retrofit) :
PlacesEndpoint {
private val endpoint by lazy { retrofit.create(PlacesEndpoint::class.java) }
override fun getVenueRecommendations(query: Map<String, String>): Call<ResponseWrapper> =
endpoint.getVenueRecommendations(query)
}
Second Unit Test
Now, add a new test called testPlacesService()
to our RetrofitClientTest
class.
class RetrofitClientTest {
@Test
fun testPlacesService() {
//Get an instance of PlacesService by proiving the Retrofit instance
val service = PlacesService(RetrofitClient().retrofit)
//Create a new request for our API calling
val query = VenueRecommendationsQueryBuilder()
.setLatitudeLongitude(52.376510, 4.905890)
.build()
//Execute the API call
val response = service.getVenueRecommendations(query).execute()
//Check for error body
val errorBody = response.errorBody()
assert(errorBody == null)
//Check for success body
val responseWrapper = response.body()
assert(responseWrapper != null)
assert(response.code() == 200)
}
}
What we want to acheive?
To verify that Retrofit
instance is provided by the respective provider. Initialize PlacesService
and test the api execution is working as expected.
Now, run the test
✔️ Tests passed: 1 of 1 test - 574ms
BUILD SUCCESSFUL in 3s
28 actionable tasks: 2 executed, 26 up-to-date
8:54:14 PM: Tasks execution finished ':app:cleanTestDebugUnitTest :app:testDebugUnitTest --tests "com.rommansabbir.test.RetrofitClientTest.testPlacesService"'.
Super Fun, Right?
That's it for today. Leave your feedback :)