当进行retrofit2请求时,单元测试Call对象为null

时间:2016-05-20 22:13:05

标签: android unit-testing mockito robolectric retrofit2

之前我的项目使用的是Retrofit,当我编写单元测试时,一切似乎都运行良好。现在,我们使用Retrofit 2.0升级到compile 'com.squareup.retrofit2:retrofit:2.0.0'。 我们正在使用Robolectric进行单元测试。 以下是我们为之前的Retrofit版本编写的测试。

        @Test
        public void testButton() throws Exception {
            button.setText("www.google.com");            
            button.performClick();    
            Mockito.verify(mockApiservice).getLinkDetails(requestArgumentCaptor.capture());
            assertThat(requestArgumentCaptor.getValue()).isEqualTo("www.google.com");         
            assertThat(button.getVisibility()).isEqualTo(View.GONE);
        }

现在,当我们升级到Retrofit 2.0时,button点击实际代码更改为

 Call<MyPOJO> callObj = ApiService.getLinkDetails(encodedUrlString);
 callObj.enqueue(this);

即使我将测试代码更改为 -

,测试也会失败
            @Test
            public void testButton() throws Exception {
                button.setText("www.google.com");            
                button.performClick();         
                assertThat(button.getVisibility()).isEqualTo(View.GONE);
            }

我现在得到的错误是 -

java.lang.NullPointerException at callObj.enqueue(this);

表示callObj为空 所以有两个最重要的问题 -

  1. 为什么我在实际代码中获得NPE?

  2. 如何更改测试代码以对模拟请求进行模拟响应?

  3. 我到处搜索,但我没有任何线索。 请帮我。任何意见都非常感谢。

    Logcat -

    java.lang.NullPointerException
        at com.myapp.MyFragment.onButtonClick(MyFragment.java:428)
        at com.myapp.fragment.MyFragment.access$100(MyFragment.java:62)
        at com.myapp.fragment.MyFragment$3.onClick(MyFragment.java:148)
        at android.view.View.performClick(View.java:4756)
        at com.myapp.MyFragmentTest.testButton(MyFragmentTest.java:122)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
        at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
        at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
        at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    

1 个答案:

答案 0 :(得分:1)

我可能已经弄清楚了 - 看起来你正在调用getLinkDetails作为静态方法,但你需要这样做:

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://url.com/")
.build();

ApiService service = retrofit.create(ApiService.class);
Call<MyPOJO> callObj = service.getLinkDetails(encodedUrlString);
callObj.enqueue(this);

您可以重复使用Retrofit对象和服务对象,但不能重用Call

改进2文档:http://square.github.io/retrofit/