当使用mockito

时间:2016-12-10 20:14:54

标签: unit-testing mockito

我有以下要测试的Java代码。我遇到的困难是弄清楚如何验证对handleAppVersionRequest的调用,实际构建AppVersionResponse对象。有没有办法用Mockito做到这一点?

此处代码是方法的代码:

class MyClass {
        public void handleAppVersionRequest(String dataStr, 
    final int dataChannelId) {
            String ver = "1.0";
            final AppVersionResponse resp = new AppVersionResponse(ver);
            Timber.d("Sending data %s", resp.toString());
            sendResponse(dataChannelId, getGson().toJson(resp));
        }
}

以下是测试方法:

@Test
public void testHandleAppVersionRequest() throws Exception {
    MyClass presenter = Mockito.spy(new MyClass());
    String versionRequestJson = "{\"command\":1}";
    when(presenter.getGson()).thenReturn(gSon);
    presenter.handleAppVersionRequest(versionRequestJson,0);
    // How do I verify that AppResponse object was constructed?
    verify(presenter,times(1)).sendResponse(anyInt(),anyString());
}

1 个答案:

答案 0 :(得分:1)

如果您必须在单元测试期间测试对象的创建,您可以提取工厂,模拟它以进行测试,然后验证是否调用了create方法它。

同时,考虑花一些时间查看Mockito的一些教程和一般的单元测试,例如this one。您应该选择一个将成为测试系统的课程。不要间谍或嘲笑这堂课!相反,将mocks作为依赖项传入,用于测试类的行为。

以下是从MyClass

中提取的工厂
class AppVersionResponseFactory {
    AppVersionResponse create(String version) {
        return new AppVersionResponse(version);
    }
}

然后是类的重构版本,其中依赖项(Gson和工厂)通过构造函数传递:

class MyClass {

    //dependencies that can now be mocked!
    private final AppVersionResponseFactory appVersionResponseFactory;
    private final Gson gson;

    //pass the mockable dependencies in the constructor of the system under test!
    public MyClass(AppVersionResponseFactory appVersionResponseFactory, Gson gson) {
        this.appVersionResposeFactory = factory;
        this.gson = gson;
    }

    public void handleAppVersionRequest(String dataStr, final int dataChannelId) {
        String ver = "1.0";
        AppVersionResponse resp = AppVersionResponseFactory.create(ver);
        Timber.d("Sending data %s", resp.toString());
        sendResponse(dataChannelId, gson.toJson(resp));
    }
}

现在您的测试看起来像这样:

//mocks
AppVersionResponseFactory mockAppVersionResposeFactory;
Gson mockGson;

//system under test
MyClass myClass;

@Before
public void setUp() {
    mockAppVersionResposeFactory = Mockito.mock(AppVersionResponseFactory.class);
    mockGson = Mockito.mock(Gson.class);
    myClass = new MyClass(mockGson, mockAppVersionResposeFactory);
}

@Test
public void testHandleAppVersionRequest() throws Exception {
    String versionRequestJson = "{\"command\":1}";

    myClass.handleAppVersionRequest(versionRequestJson, 0);

    verify(appVersionResposeFactory).create("1.0");
}

请注意,尽管您的问题要求验证对象构造的方法,但更好的测试可能会测试该方法的最终结果,即使用正确的dataChannelId和正确的JSON调用sendResponse。您可以在此答案中使用相同的技术来执行此操作,即提取依赖项(可能是ResponseSender?),将其传递给MyClass的构造函数,在测试中模拟它,然后调用verify在它上面。