Skip to content

Instantly share code, notes, and snippets.

@crgarridos
Last active December 13, 2018 11:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save crgarridos/baceca0b3ddf7053b9874e9a5b1d00b4 to your computer and use it in GitHub Desktop.
Save crgarridos/baceca0b3ddf7053b9874e9a5b1d00b4 to your computer and use it in GitHub Desktop.
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'org.immutables:gson:2.7.3'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
testImplementation 'junit:junit:4.12'
testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0'
package com.cristiangarrido.example.recyclerview
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import org.junit.Assert
import org.junit.Test
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import java.lang.Exception
data class DataClass(val id: Int, val name: String) {
companion object {
fun fromJson(json: String): DataClass =
Gson().fromJson(json, DataClass::class.java)
}
}
interface ApiService {
@GET("endpoint")
fun getData(): Call<DataClass>
@GET("endpoint")
fun getDataAsMap(): Call<Map<String, Any?>>
}
class RetrofitTest {
@Test
fun `test 200 with valid body`() {
serve(MockResponse().setResponseCode(200).setBody("""{"id":1,"name":"Chichi"}""")) { api ->
val response = api.getData().execute()
Assert.assertTrue(response.isSuccessful)
Assert.assertEquals("Chichi", response.body()?.name)
}
}
@Test
fun `test 500 with valid body`() {
serve(MockResponse().setResponseCode(500).setBody("""{"id":1,"name":"Chichi"}""")) { api ->
val response = api.getData().execute()
Assert.assertFalse(response.isSuccessful)
val responseBody = response.errorBody()?.string()!!
Assert.assertEquals("Chichi", DataClass.fromJson(responseBody).name)
}
}
@Test(expected = IllegalStateException::class)//Cannot read raw response body of a converted body.
fun `test 200 with invalid body`() {
serve(MockResponse().setResponseCode(200).setBody("""{"code":500,"message":"Server error"}""")) { api ->
val response = api.getData().execute()
Assert.assertTrue(response.isSuccessful)
Assert.assertNull(response.body()?.name)//<- but I still having a DataClass instance !!
val responseBody = response.raw().body()?.string()!!
Assert.assertEquals("Chichi", DataClass.fromJson(responseBody).name)
}
}
@Test
fun `test 200 with invalid body as map`() {
serve(MockResponse().setResponseCode(200).setBody("""{"code":"500","message":"Server error"}""")) { api ->
val response = api.getDataAsMap().execute()
Assert.assertTrue(response.isSuccessful)
val responseBody = response.body()!!
Assert.assertEquals("500", responseBody["code"])
}
}
@Test
fun `test 200 with not quoted keys of json`() {
serve(MockResponse().setResponseCode(200).setBody("""{code:"500",message:"Server error"}""")) { api ->
val response = api.getDataAsMap().execute()
Assert.assertTrue(response.isSuccessful)
val responseBody = response.body()!!
Assert.assertEquals("500", responseBody["code"])
}
}
@Test
fun `test 200 enqueue succeeded with invalid json`() {
var onFailureCalled = false
var onResponseCalled = false
serve(MockResponse().setResponseCode(200).setBody("""{code:"500",message:"Server error"}""")) { api ->
api.getData().enqueue(object : Callback<DataClass> {
override fun onFailure(call: Call<DataClass>, t: Throwable) {
onFailureCalled = true
}
override fun onResponse(call: Call<DataClass>, response: Response<DataClass>) {
onResponseCalled = true
}
})
Thread.sleep(200)
Assert.assertTrue(onResponseCalled)
Assert.assertFalse(onFailureCalled)
}
}
@Test
fun `test 500 enqueue succeeded with invalid json`() {
var onFailureCalled = false
var onResponseCalled = false
serve(MockResponse().setResponseCode(500).setBody("""{code:"500",message:"Server error"}""")) { api ->
api.getData().enqueue(object : Callback<DataClass> {
override fun onFailure(call: Call<DataClass>, t: Throwable) {
onFailureCalled = true
}
override fun onResponse(call: Call<DataClass>, response: Response<DataClass>) {
onResponseCalled = true
}
})
Thread.sleep(200)
Assert.assertTrue(onResponseCalled)
Assert.assertFalse(onFailureCalled)
}
}
private fun serve(response: MockResponse, useServer: (ApiService) -> Unit) {
val mockServer = MockWebServer().apply {
enqueue(response)
start()
val retrofit = Retrofit.Builder()
.baseUrl(this.url("/"))
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create()))//<- setLenient to the rescue
.build()
useServer(retrofit.create(ApiService::class.java))
}
mockServer.shutdown()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment