首页 > 解决方案 > 模拟单元测试需要但未调用:

问题描述

我已经看到 SO 中已经存在类似的问题,我尝试了所有解决方案,但无法解决我的问题,因为我是新手tdd

我有这样的课

public class AppUpdatesPresenter  {

    public void stopService() {
        ServiceManager.on().stopService();
    }
}

我有这样的测试课

@RunWith(MockitoJUnitRunner.class)
public class AppUpdatesPresenterTest {
       @Mock
       AppUpdatesPresenter appUpdatesPresenter;

       @Mock
       ServiceManager serviceManager;

       @Mock
       Context context;

       @Test
       public void test_Stop_Service() throws Exception {
            appUpdatesPresenter.stopService();
            verify(serviceManager,times(1)).stopService();
       }

}

当我尝试测试时,如果我调用stopService()方法,则ServiceManager.on().stopService();至少调用一次。

但我收到以下错误

Wanted but not invoked:
serviceManager.stopService();
-> at io.example.myapp.ui.app_updates.AppUpdatesPresenterTest.test_Stop_Service(AppUpdatesPresenterTest.java:103)
Actually, there were zero interactions with this mock.

不知道出了什么问题。

标签: junitmockitotdd

解决方案


当你打电话时appUpdatesPresenter.stopService();,什么也没发生,因为你没有告诉它应该发生什么。

要使您的测试通过,您需要将appUpdatesPresenter.

@Test
public void test_Stop_Service() throws Exception {
    doAnswer { serviceManager.stopService(); }.when(appUpdatesPresenter).stopService()
    appUpdatesPresenter.stopService();
    verify(serviceManager).stopService();
}

顺便说一句,上面的测试毫无意义,因为你把所有的东西都存根了。


为了使测试用例有意义,您应该注入ServiceManager不是将其与AppUpdatePresenter.

public class AppUpdatesPresenter  {
    private final ServiceManager serviceManager;

    public AppUpdatesPresenter(ServiceManager serviceManager) {
        this.serviceManager = serviceManager;
    }

    public void stopService() {
        sm.stopService();
    }
}

然后进行AppUpdatesPresenter待测。

@InjectMock AppUpdatesPresenter appUpdatesPresenter;

现在,测试用例不再依赖于预设交互,而是依赖于代码的真实实现。

@Test
public void test_Stop_Service() throws Exception {
    appUpdatesPresenter.stopService();
    verify(serviceManager).stopService();
}

推荐阅读