-
Notifications
You must be signed in to change notification settings - Fork 0
How to mock classes that are not built using the dependency injection principles
Devrath edited this page Jun 26, 2021
·
2 revisions
There are many cases where the classes are not built using the dependency injection and we need to test those classes
We can use mockK object for this
SpacingOutApi
interface SpacingOutApi {
companion object {
fun create(): SpacingOutApi {
val client = OkHttpClient.Builder().addInterceptor { chain ->
val url = chain.request().url().newBuilder().addQueryParameter("api_key", "IaZbUHgLeD5G3evuRL0ZDlaAXP9bIVPU919Gt9CF").build()
val request = chain.request().newBuilder().url(url).build()
chain.proceed(request)
}.build()
return Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create())
.baseUrl("https://api.nasa.gov")
.client(client)
.build()
.create(SpacingOutApi::class.java)
}
}
/*@GET("/planetary/apod")
fun getImage(@Query("date") date: String): Call<ApodImage>*/
@GET("/planetary/apod")
suspend fun getImage(@Query("date") date: String): ApodImage
@GET("/planetary/earth/imagery/")
suspend fun getEarthImagery(@Query("lon") longitude: Float, @Query("lat") latitude: Float): EarthImage
}
Test class
@Test
fun `a image is sent through the view after the co-ordinates are entered`() {
/*** ****************** BLOCK TO MOCK THE API ****************** ***/
val mockApi = mockk<SpacingOutApi>()
// Using the mockK object you can mock the kotlin objects and return what you want
mockkObject(SpacingOutApi)
// After above step you can check using mocking syntax you can return what you want
// Now in below line whenever we mock the api, we can ensure we return the mockApi that is needed
every { SpacingOutApi.create() } returns mockApi
/*** ****************** BLOCK TO MOCK THE API ****************** ***/
coEvery { mockApi.getEarthImagery(any(),any()) } answers {
EarthImage("TestUrl")
}
val viewModel = LookupViewModel()
viewModel.latLongInput(latitude = 10f,longitude = 10f)
assertEquals("TestUrl",viewModel.imageLiveData.value)
}
- There is a scenario where it accepts a certain set of input values.
- Now again it adds certain more values to it.
- Then calls the third-party service using old values appended with new values.
@Test
fun `new analytics events are added before the events are sent`() {
mockkObject(ThirdPartyAnalyticsProvider)
// Lets use the combination of slot and capture
// slot is a capturing tool used to capture the arguments
val slot = slot<Map<String,String>>()
every { ThirdPartyAnalyticsProvider.logEvent(any(),capture(slot)) } just Runs
SpacingAnalytics().logEvent("Test event", mapOf("attribute" to "value"))
// Now you expect to call the third party analytics with the value you supplied along with other attributes
val expected = mapOf(
"attribute" to "value",
"client_type" to "Android",
"version" to "1"
)
// List of attributes passed to the analytics was captured in the slot previously supplied earlier
assertEquals(expected,slot.captured)
}