如何对 Retrofit api 调用进行单元测试? [英] How to unit test Retrofit api calls?

查看:21
本文介绍了如何对 Retrofit api 调用进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为每个可能的代码块集成单元测试用例.但是我在为 通过改造进行的 api 调用添加测试用例时遇到了问题.

I am trying to integrate Unit test cases for every chunk of code possible. But I am facing issues while adding test cases for api calls that are made through retrofit.

JUnit 编译器从不执行回调函数中的代码.

The JUnit compiler never executes the code in the CallBack functions.

还有另一种选择使所有 api 调用同步以进行测试,但这并非适用于我的应用中的所有情况.

There is another option of making all the api calls Synchronous for testing purpose, but that's not possible for every case in my app.

我该如何解决这个问题?我必须以任何方式在 api 调用中添加测试用例.

How can I sort this out? I have to add test cases in the api calls by any means.

推荐答案

我使用 Mockito、Robolectric 和 Hamcrest 库测试我的 Retrofit 回调.

I test my Retrofit callbacks using Mockito, Robolectric and Hamcrest libraries.

首先,在你的模块的 build.gradle 中设置 lib 栈:

First of all, set up lib stack in your module's build.gradle:

dependencies {
    testCompile 'org.robolectric:robolectric:3.0'
    testCompile "org.mockito:mockito-core:1.10.19"
    androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
}

在 jour 项目的全局 build.gradle 中添加以下行到 buildscript 依赖项:

In jour project's global build.gradle add following line to buildscript dependencies:

classpath 'org.robolectric:robolectric-gradle-plugin:1.0.1'

然后在 Android Studio 中进入Build Variants"菜单(为了快速找到它,按 Ctrl+Shift+A 并搜索它),并将Test Artifact"选项切换到Unit Tests".Android Studio 会将您的测试文件夹切换到com.your.package (test)"(而不是 androidTest).

Then enter "Build Variants" menu in Android Studio (to quickly find it, hit Ctrl+Shift+A and search for it), and switch "Test Artifact" option to "Unit Tests". Android studio will switch your test folder to "com.your.package (test)" (instead of androidTest).

好的.设置完成,是时候写一些测试了!

Ok. Set-up is done, time to write some tests!

假设您有一些改造 api 调用来检索需要放入 RecyclerView 等某些适配器中的对象列表.我们想测试适配器是否在成功调用时填充了正确的项目.为此,我们需要切换您用来通过模拟进行调用的 Retrofit 接口实现,并利用 Mockito ArgumentCaptor 类进行一些虚假响应.

Let's say you've got some retrofit api calls to retrieve a list of objects that need to be put into some adapter for a RecyclerView etc. We would like to test whether adapter gets filled with proper items on successful call. To do this, we'll need to switch your Retrofit interface implementation, that you use to make calls with a mock, and do some fake responses taking advantage of Mockito ArgumentCaptor class.

@Config(constants = BuildConfig.class, sdk = 21,
    manifest = "app/src/main/AndroidManifest.xml")
@RunWith(RobolectricGradleTestRunner.class)
public class RetrofitCallTest {

    private MainActivity mainActivity;

    @Mock
    private RetrofitApi mockRetrofitApiImpl;

    @Captor
    private ArgumentCaptor<Callback<List<YourObject>>> callbackArgumentCaptor;

    @Before
    public void setUp() {            
        MockitoAnnotations.initMocks(this);

        ActivityController<MainActivity> controller = Robolectric.buildActivity(MainActivity.class);
        mainActivity = controller.get();

        // Then we need to swap the retrofit api impl. with a mock one
        // I usually store my Retrofit api impl as a static singleton in class RestClient, hence:
        RestClient.setApi(mockRetrofitApiImpl);

        controller.create();
    }

    @Test
    public void shouldFillAdapter() throws Exception {
        Mockito.verify(mockRetrofitApiImpl)
            .getYourObject(callbackArgumentCaptor.capture());

        int objectsQuantity = 10;
        List<YourObject> list = new ArrayList<YourObject>();
        for(int i = 0; i < objectsQuantity; ++i) {
            list.add(new YourObject());
        }

        callbackArgumentCaptor.getValue().success(list, null);

        YourAdapter yourAdapter = mainActivity.getAdapter(); // Obtain adapter
        // Simple test check if adapter has as many items as put into response
        assertThat(yourAdapter.getItemCount(), equalTo(objectsQuantity));
    }
}

通过右键单击测试类并点击运行来继续测试.

Proceed with the test by right clicking the test class and hitting run.

就是这样.我强烈建议使用 Robolectric(带有 robolectric gradle 插件)和 Mockito,这些库使测试 android 应用程序变得更加容易.我从以下 博文.另请参阅此答案.

And that's it. I strongly suggest using Robolectric (with robolectric gradle plugin) and Mockito, these libs make testing android apps whole lotta easier. I've learned this method from the following blog post. Also, refer to this answer.

更新:如果您在 RxJava 中使用 Retrofit,请查看 我对此的其他回答 也是.

Update: If you're using Retrofit with RxJava, check out my other answer on that too.

这篇关于如何对 Retrofit api 调用进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆