单元测试类,仅使用局部变量进行合成

时间:2017-10-16 09:48:36

标签: java spring unit-testing mocking

我正在编写使用具有非常相似属性的各种REST api端点的应用程序。唯一的区别在于端点地址和有效负载。标题,方法和其他内容保持不变。这就是为什么我创建了与远程主机通信的类,它被称为RestApiCommunicator,其方法generateRequestAndCallEndpoint(List payload)包含有效负载以及执行休息呼叫所需的所有必需内容。 比,我有各种类只调用这个通信器类与适当的端点后缀及其资源。 一切都很好,但我想对所有这些类进行单元测试。我试图通过阅读很多SO问题来弄清楚如何做到这一点,但它们是相当复杂的情况,我很简单。 我试图找出一种正确的单元测试类似于这个类的方法:

class MyRestClient {

    public void useRestApi(List<MyResources> myResources) {
        RestApiCommunicator restApiCommunicator = new RestApiCommunicator ("/some/endpoint");
        restApiCommunicator.generateRequestAndCallEndpoint(myResources);
    }
}

我想测试是否使用正确的enpoint地址创建了传播者,并且如果使用我的样本有效负载,generateRequestAndCallEndpoint被称为exacly一次。

我想到的只是让restApiCommunicator成为一个字段,为这个字段创建setter并在单元测试中模拟它。但在我看来这是一个相当脏的解决方案,我不想修改我的代码以允许测试。

也许你可以指出我可以用一些好的模式测试这个课程的方向。

(ps。如果重要 - 这是一个Spring Boot应用程序)

2 个答案:

答案 0 :(得分:0)

您可以为沟通者提供工厂

class MyRestClient {
    private RestApiCommunicatorFactory factory = ...

    public void useRestApi(List<MyResources> myResources) {
        factory.getCommunicator("/some/endpoint")
            .generateRequestAndCallEndpoint(myResources);
    }

在您的单元测试中,您提供了工厂的模拟,它返回模拟通信器。具体的语言取决于您选择的模拟库。

答案 1 :(得分:0)

一种方法可以完全按照你的要求进行(例如,&#34;测试通信器是否使用正确的enpoint地址创建,如果generateRequestAndCallEndpoint只使用我的样本有效负载调用了一次&#34;)就是模拟它使用JMockit:

public final class MyRestClientTest {
    @Tested MyRestClient restClient;
    @Mocked RestApiCommunicator restApi;

    @Test
    public void verifyUseOfRestApi() {
        List<MyResource> resources = asList(new MyResource("a"), new MyResource("b"));

        restClient.useRestApi(resources);

        new Verifications() {{
            new RestApiCommunicator("/some/endpoint");
            restApi.generateRequestAndCallEndpoint(resources); times = 1;
        }};
    }
}