java - Android 测试 - Robolectric + Mockito + Retrofit 出现 Wanted 但未调用错误

标签 java android mockito retrofit robolectric

尝试使用 Robolectric 和 Mockito 在 Android 应用程序中测试我的 Retrofit 调用,但出现以下错误:

Wanted but not invoked: mockApi.register( , ); -> at ServiceTest.testAPI(ServiceTest.java:58) Actually, there were zero interactions with this mock.

RetroFit API 调用在接口(interface)中定义如下:

@FormUrlEncoded
@POST("/register")
void register(
        @FieldMap Map<String, String> registrationParams,
        Callback<JsonObject> response) ;

我的测试类如下:

@Config(constants = BuildConfig.class)
@RunWith(TestRunner.class)
public class SharedServiceTest {

private RegistrationActivity activity;
@Mock
private SharedService mockApi;

@Captor
private ArgumentCaptor<Callback<JsonObject>> cb;


@Before
public void setUp() {

    MockitoAnnotations.initMocks(this);
    ActivityController<RegistrationActivity> controller = Robolectric.buildActivity(RegistrationActivity.class);
    activity = controller.get();

    controller.create();
}

@Test
public void testAPI() throws Exception {

    activity.populateFields();
    activity.validateFields();
    activity.register("");

    Mockito.verify(mockApi).register(Mockito.anyMap(), cb.capture());

    JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("sessionToken", Mockito.anyString());
    jsonObject.addProperty("userId", Mockito.anyString());

    cb.getValue().success(jsonObject, null);

    Assert.assertTrue(ShadowToast.getTextOfLatestToast().contains("Registration completed"));

}

}

我的RegistrationActivity中使用API​​的方法如下:

public void register(){

       MyApplication.getInstance().getSharedService().register(mRegistrationParams, new Callback<JsonObject>() {
            @Override
            public void success(JsonObject jsonObject, retrofit.client.Response response) {
                Toast.makeText(RegistrationActivity.this, "Registration completed", Toast.LENGTH_LONG).show();
            }

            @Override
            public void failure(RetrofitError error) {
                Toast.makeText(RegistrationActivity.this, RetrofitUtils.getErrorMessage(error), Toast.LENGTH_LONG).show();
            }
        });

    }

真正的Retrofit服务来 self 自己的Application类,我在我的测试文件夹中模拟了它以供robolectric使用:

public class TestMyApplication extends MyApplication
        implements TestLifecycleApplication {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override public void beforeTest(Method method) {
    }

    @Override public void prepareTest(Object test) {
    }

    @Override public void afterTest(Method method) {
    }

    @Override public CPSharedService getCPSharedService() {
        return Mockito.mock(SharedService.class);
    }
}

我已经搜索了有关此错误的其他问题,但没有一个与我在这里尝试执行的操作或为我的问题提供解决方案相匹配,所以我只是想知道我做错了什么?

最佳答案

TestMyApplicationSharedService 的模拟实例与您声明的测试类不同。 Mockito.verify(mockApi).register(Mockito.anyMap(), cb.capture()); 失败,因为 mockApi 字段引用的实例实际上从未被调用。 另一个问题是 TestMyApplication 中的 getter 总是为每次调用返回一个新的模拟:

    @Override public CPSharedService getCPSharedService() {
        return Mockito.mock(SharedService.class); //this creates a new "mocked" instance 
    }

您的场景对我来说并不是 100% 清楚,但如果您可以让您的测试在 TestMyApplication 实例中设置 mockApi 字段的实例,那就更好了:

public class TestMyApplication extends MyApplication
        implements TestLifecycleApplication {

    private SharedService sharedService;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override public void beforeTest(Method method) {
    }

    @Override public void prepareTest(Object test) {
    }

    @Override public void afterTest(Method method) {
    }

    @Override public CPSharedService getCPSharedService() {
        return this.sharedService;
    }

    public void setCPSharedService(SharedService sharedService) {
        // store your mock
        this.sharedService = sharedService;
    }
}

在你的测试类中:

@Test
public void testAPI() throws Exception  {

    // configure you TestMyApplication
    assertTrue(MyApplication.getInstance() instanceof TestMyApplication);
    TestMyApplication testMyApp = (TestMyApplication) MyApplication.getInstance();
    testMyApp.setCPSharedService(this.mockApi);

    activity.populateFields();
    activity.validateFields();
    activity.register("");

    Mockito.verify(this.mockApi).register(Mockito.anyMap(), cb.capture());

    ...

}

关于java - Android 测试 - Robolectric + Mockito + Retrofit 出现 Wanted 但未调用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37989626/

相关文章:

Java 控制台输出 - 文件和控制台两者

java - 什么时候使用 try multi catch?

android - Flutter Firestore QuerySnapshot 没有 getter 'document 的实例

java - 模拟父类(super class)方法 Mockito 测试用例

java - 为什么此测试 junit 测试返回 400?

java - 我应该使用额外的类或设计实例的样式吗?

Java Set of Maps hashCode 不正确?

javascript - jQueryMobile 应用程序中的事件触发两次

android - SharedPreferences 保存按钮更改后不可见单击它并让出现另一个按钮

java - 如何在每次调用 doReturn 时返回一个新实例?