java - 如何使用 mockito 测试 REST 服务?

标签 java unit-testing rest mockito

我是 Java 单元测试的新手,听说 Mockito 框架非常适合用于测试目的。

我已经开发了一个 REST 服务器(CRUD 方法),现在我想测试它,但我不知道怎么做?

我更不知道这个测试程序应该如何开始。我的服务器应该在 localhost 上运行,然后在该 url 上进行调用(例如 localhost:8888)?

这是我目前尝试的方法,但我很确定这不是正确的方法。

    @Test
    public void testInitialize() {
        RESTfulGeneric rest = mock(RESTfulGeneric.class);

        ResponseBuilder builder = Response.status(Response.Status.OK);

        builder = Response.status(Response.Status.OK).entity(
                "Your schema was succesfully created!");

        when(rest.initialize(DatabaseSchema)).thenReturn(builder.build());

        String result = rest.initialize(DatabaseSchema).getEntity().toString();

        System.out.println("Here: " + result);

        assertEquals("Your schema was succesfully created!", result);

    }

这是 initialize 方法的代码。

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/initialize")
    public Response initialize(String DatabaseSchema) {

        /** Set the LogLevel to Info, severe, warning and info will be written */
        LOGGER.setLevel(Level.INFO);

        ResponseBuilder builder = Response.status(Response.Status.OK);

        LOGGER.info("POST/initialize - Initialize the " + user.getUserEmail()
                + " namespace with a database schema.");

        /** Get a handle on the datastore itself */
        DatastoreService datastore = DatastoreServiceFactory
                .getDatastoreService();


        datastore.put(dbSchema);

        builder = Response.status(Response.Status.OK).entity(
                "Your schema was succesfully created!");
        /** Send response */
        return builder.build();
    }

在这个测试用例中,我想向服务器发送一个 Json 字符串(POST)。如果一切顺利,服务器应回复“您的架构已成功创建!”。

有人可以帮帮我吗?

最佳答案

好的。因此,该方法的约定如下:将输入字符串解析为 JSON,如果无效则返回 BAD_REQUEST。如果有效,则在 datastore 中创建一个具有各种属性(您知道它们)的实体,然后返回 OK

并且您需要验证该方法是否履行了此契约(Contract)。

Mockito 在这方面有何帮助?好吧,如果你在没有 Mockito 的情况下测试这个方法,你需要一个真正的 DataStoreService,并且你需要在这个真正的 DataStoreService 中验证实体是否被正确创建。这就是您的测试不再是单元测试的地方,这也是测试太复杂、太长、太难运行的地方,因为它需要一个复杂的环境。

Mockito 可以通过模拟对 DataStoreService 的依赖项来提供帮助:您可以创建一个 DataStoreService 的模拟,并验证这个模拟确实是使用适当的实体参数调用的您在测试中调用 initialize() 方法。

为此,您需要能够将 DataStoreService 注入(inject)到您的测试对象中。它可以像通过以下方式重构对象一样简单:

public class MyRestService {
    private DataStoreService dataStoreService;

    // constructor used on the server
    public MyRestService() {
        this.dataStoreService = DatastoreServiceFactory.getDatastoreService();
    }

    // constructor used by the unit tests
    public MyRestService(DataStoreService dataStoreService) {
        this.dataStoreService = dataStoreService;
    }

    public Response initialize(String DatabaseSchema) {
         ...
         // use this.dataStoreService instead of datastore
    }
}

现在在你的测试方法中,你可以这样做:

@Test
public void testInitializeWithGoodInput() {
    DataStoreService mockDataStoreService = mock(DataStoreService.class);
    MyRestService service = new MyRestService(mockDataStoreService);
    String goodInput = "...";
    Response response = service.initialize(goodInput);
    assertEquals(Response.Status.OK, response.getStatus());

    ArgumentCaptor<Entity> argument = ArgumentCaptor.forClass(Entity.class);
    verify(mock).put(argument.capture());
    assertEquals("the correct kind", argument.getValue().getKind());
    // ... other assertions
}

关于java - 如何使用 mockito 测试 REST 服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10775254/

相关文章:

unit-testing - Grails 1.3.3:未填充controller.redirectArgs.action

java - 如何编码 URI 参数值?

rest - 资源是否始终位于 REST 中的服务器上?

python - 我应该使用 GET 还是 POST 来检索结果 Django

java - 日历Java程序: How can I condense this code?

java - Java 中类的作用

java - 如何从 Hibernate session 中分离所有对象

javascript - 如何使用 Sinon.js stub 动态对象方法?

java - 关于java中GUI的问题

unit-testing - 如何在单元测试期间使用 vue-test-utils 和 jest 模拟 mixin?