使用Call无效的模拟Retrofit响应调用

Jim*_*nts 13 android retrofit2 okhttp3

我在嘲笑APIService的反应.不幸的是它不起作用,我必须发回一个电话,但我不明白如何.问题是如何发送回Call对象.

@RunWith(AndroidJUnit4::class)
class ApiServiceTest {

    @Test
    fun testSomething() {
        val apiService = ApiServiceMock()
        val call = apiService.getStep1User()
        val result = call.execute()
        Assert.assertEquals("SomeUserValue", result.body()!!.getResponse())
    }
}
Run Code Online (Sandbox Code Playgroud)

这是模拟服务:

class ApiServiceMock : ApiService {
    override fun getStep1User(): Call<UserResponse> {
        // How to return an object of type Call<UserResponse> ?
        val response = "{ \"Response\": \"SomeUserValue\" }"
        val gson = Gson().toJson(response)
        return Response.success(gson)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是api接口:

interface ApiService {

    @GET("/booky/step1user")
    fun getStep1User(): Call<UserResponse>

    companion object {

        val interceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
        val client = OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build()

        val retrofit = Retrofit.Builder()
                .baseUrl("http://jimclermonts.nl")
                .addConverterFactory(MoshiConverterFactory.create().asLenient())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build()
    }
}
Run Code Online (Sandbox Code Playgroud)

的build.gradle:

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.3.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation "com.squareup.retrofit2:adapter-rxjava2:2.3.0"

implementation 'com.google.code.gson:gson:2.8.0'

testImplementation "org.mockito:mockito-core:2.12.0"
testImplementation "com.nhaarman:mockito-kotlin:1.5.0"
implementation 'org.mockito:mockito-android:2.18.0'
Run Code Online (Sandbox Code Playgroud)

Tpo*_*6oH 9

调用是一个接口,您可以创建一个实现它的对象并从模拟方法返回它:

class ApiServiceMock : ApiService {
    override fun getStep1User(): Call<UserResponse> {
        return object: Call<SignedUserUi> {
            override fun enqueue(callback: Callback<UserResponse>?) {
            }

            override fun isExecuted(): Boolean {
                return false
            }

            override fun clone(): Call<UserResponse> {
                return this
            }

            override fun isCanceled(): Boolean {
                return false
            }

            override fun cancel() {

            }

            override fun request(): Request {
                return Request.Builder().build()
            }

            override fun execute(): Response<UserResponse> {
                // Create your mock data in here
                val response = "{ \"Response\": \"SomeUserValue\" }"
                val gson = Gson().toJson(response)
                return Response.success(UserResponse(gson))
            }

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想拥有更少的样板并且能够在一行中模拟接口,我建议你看一下mockito for kotlin.

将它包含在您的项目中之后,您将能够做到

val rawResponse = "{ \"Response\": \"SomeUserValue\" }"
val gson = Gson().toJson(rawResponse)
val response = Response.success(UserResponse(gson))

val mockCall = mock<Call<UserResponse>> {
    on { execute() } doReturn response
}

val mockApiService = mock<ApiService> {
    on { getStep1User() } doReturn mockCall
}
Run Code Online (Sandbox Code Playgroud)


Fak*_*her 5

你要做的是testin改造!您必须在获得响应后断言您的应用程序的行为,而不是断言什么改进得到请求的响应!例如断言错误响应,必须出现错误对话框.

您可以使用OkHTTPMock服务器模拟响应.在build.gradle模块文件中添加依赖项:

testImplementation 'com.squareup.okhttp3:mockwebserver:lastVersion'
Run Code Online (Sandbox Code Playgroud)

然后在您的测试文件中,您可以模拟服务器,请求和响应.这里有一个例子:

MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setBody("{ \"Response\": \"SomeUserValue\" }"));
// Start the server.
  server.start();

//and than load your request. Be Careful, they are executed in the order that you enqued them!

//Add your assertion (Succes response and error response)
//if you are working with MVP architecture, you can assert for the success case
//that method showData(data) is called using Mockito.
verify(myPresenter).showData(data);
Run Code Online (Sandbox Code Playgroud)

看看OkHttpMock 的官方示例


rad*_*los 5

You can use RETURNS_DEEP_STUBS. But not sure how does it work in Kotlin.

mock = Mockito.mock(Api.class, RETURNS_DEEP_STUBS)
when(mock.getSomething().execute()).thenReturn(Response.success(...));
Run Code Online (Sandbox Code Playgroud)