-
Notifications
You must be signed in to change notification settings - Fork 0
Checking if a method in the API interface is called
Devrath edited this page Jun 26, 2021
·
3 revisions
- Consider we need to validate a service, This service returns a list of images
- We need to check that if the number of images returned is 30
- Here some of the challenges we face are that How to mock the service and going further how to check using the service the API returns a certain type of API response and further there are 30 images present in it.
ImageListProvider.kt
class ImageListProvider(private val api: SpacingOutApi) {
// Requests 30 images from the API
private val numImages = 30
suspend fun buildImageList(): List<ApodImage> = coroutineScope {
val today = LocalDate.now()
val deferredImages = mutableListOf<Deferred<ApodImage>>()
for (i in 0 until numImages) {
val day = today.minusDays(i.toLong())
val image = async(Dispatchers.IO) {
api.getImage(day.format(DateTimeFormatter.ISO_DATE)).execute().body()!!
}
deferredImages.add(image)
}
deferredImages.map { it.await() }
}
}
SpacingOutApi.kt
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/earth/imagery/")
suspend fun getEarthImagery(@Query("lon") longitude: Float, @Query("lat") latitude: Float): EarthImage
}
Test
/**
* RunBlockingTest is used to ensure that the all the coroutines that are involved
* in the test are completed before the test finishes
**/
@Test
fun `a list of 30 images is returned from a api service`() = runBlocking {
// When
val expectedOutput = 30
// Since this test needs a api as input - We will use MockK to mock the interface
val spacingApi = mockk<SpacingOutApi>()
// Now once the mock is available, we want to ensure its returning the real value that you want it to return when invoked in real code
// Here in our case when we call the the function the in interface and get the object the function returns
// Here only the type matters more than the data in it
// ANSWERS: This will return whatever the block return whenever the block is executed.
every {
spacingApi.getImage(date = any())
} answers {
Calls.response(
ApodImage(
date = "01-01-2020",
explanation = "Image is of some response",
hdurl = "www.testurl.com",
title = "test",
url = "www.testurl.com",
media_type = "video"
)
)
}
// -----------------------------------------> SUT
val provider = ImageListProvider(api = spacingApi)
val images = provider.buildImageList()
// Then
assertEquals(expectedOutput,images.size)
}