MockWebServer and Retrofit with Callback

∥☆過路亽.° 提交于 2020-01-01 02:35:24

问题


I would like to simulate network communication by MockWebServer. Unfortulatelly retrofit callbacks are never invoking. My code:

    MockWebServer server = new MockWebServer();
    server.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));
    server.play();

    RestAdapter restAdapter = new RestAdapter.Builder().setConverter(new MyGsonConverter(new Gson()))
            .setEndpoint(server.getUrl("/").toString()).build();

    restAdapter.create(SearchService.class).getCount(StringUtils.EMPTY,
            new Callback<CountContainer>() {

                @Override
                public void success(CountContainer countContainer, Response response) {
                    System.out.println("success");
                }

                @Override
                public void failure(RetrofitError error) {
                    System.out.println("error");
                }
            });

    server.shutdown();

When i use retrofit without callbacks it works.


回答1:


By having a Callback you are telling Retrofit to invoke the request and call the callback asynchronously. This means that your test is exiting before anything happens.

There are two ways to get this to work:

  • Use a lock at the end of the test and wait until one of the callback methods are invoked.
  • Pass an instance of a synchronous Executor (one that just calls .run() immediately) to setExecutors on the RestAdapter.Builder so that the background invocations and callback invocations happen synchronously.



回答2:


For retrofit 2 see the answer here: https://github.com/square/retrofit/issues/1259 You can supply the synchronous executor to an OkHttpClient (via its dispatcher) and set this client to the Retrofit.Builder. You can also set the same executor to the callbackExecutor.

For example:

CurrentThreadExecutor currentThreadExecutor = new CurrentThreadExecutor();
okhttp3.Dispatcher dispatcher = new okhttp3.Dispatcher(currentThreadExecutor);
OkHttpClient okHttpClient = new 
OkHttpClient.Builder().dispatcher(dispatcher).build();

new Retrofit.Builder()
        .client(okHttpClient)
        .baseUrl(httpUrl)
        .addConverterFactory(JacksonConverterFactory.create())
        .callbackExecutor(currentThreadExecutor)
        .build();

Example of CurrentThreadExecutor implementation: https://gist.github.com/vladimir-bukhtoyarov/38d6b4b277d0a0cfb3af




回答3:


Alternatively you could use Mockinizer with MockWebServer:

OkHttpClient.Builder()
        .addInterceptor(loggingInterceptor)
        .mockinize(mocks) // <-- just add this line
        .build()

And the requests/responses that you want to mock you can define in the mocks value. In your case it would look something like:

package com.appham.mockinizer.demo

import com.appham.mockinizer.RequestFilter
import okhttp3.mockwebserver.MockResponse

val mocks: Map<RequestFilter, MockResponse> = mapOf(

    RequestFilter("/") to MockResponse().apply {
        setResponseCode(200)
        setBody("""{}""")
    }

)

See https://github.com/donfuxx/Mockinizer



来源:https://stackoverflow.com/questions/24489882/mockwebserver-and-retrofit-with-callback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!