如何使用对的Mockito测试REST服务?(How to use mockito for test

2019-06-24 20:53发布

我在Java单元测试非常新,我听说框架的Mockito是用于测试目的真的很好。

我公司开发的REST服务器(CRUD方法),现在我要测试,但我不知道怎么样?

更不知该测试程序应该如何开始。 我的服务器应该在localhost工作,然后对这个URL调用(如本地主机: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)。 如果一切顺利,则服务器应该以“你的模式是创建成功!”回复。

有人可以帮帮我吗?

Answer 1:

好。 因此,该方法的合同如下:解析输入字符串作为JSON,并发送回BAD_REQUEST如果它是无效的。 如果它是有效的,建立在实体datastore与各种属性(你认识他们),并发送回OK

而你需要验证,该合同是由方法来实现。

哪里帮助的Mockito这里? 好吧,如果你没有测试此的Mockito的方法,你需要一个真正的DataStoreService ,你需要验证实体已经在这个真正的正确创建DataStoreService 。 这是你的测试是不是一个单元测试了,这也是它太复杂了测试,太长,太难以运行,因为它需要一个复杂的环境。

可以的Mockito通过嘲讽的依赖帮助DataStoreService :您可以创建一个模拟DataStoreService ,并确认这个模拟确实与适当的实体参数调用,当你打电话给你initialize()方法,在您的测试。

要做到这一点,你需要能够将注入DataStoreService到您的被测物。 它可以在下面的方式重构你的对象一样容易:

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
}


Answer 2:

什么你在谈论听起来更像集成测试不会有太大的使用你的和的Mockito(或任何其他嘲讽框架)。

如果你想你写单元测试代码,肯定的Mockito是一个有用的工具。

我建议你阅读更多关于嘲讽/单元测试和它应该被使用的情况。



Answer 3:

的Mockito(通常)用于测试的代码部分 ; 例如,如果你在你的消费REST服务,但不想做一个全栈测试,你会嘲笑那个连接到REST服务,让您精确,和一致,测试特定问题的服务。

为了测试REST服务(例如,特定服务方法)的内部部分没有碰到一个数据库,你会嘲笑DB子系统,只允许内部服务测试,不涉及DB。 该试验属于REST服务模块,而不是客户端凹进去了。

为了测试REST服务本身你使用真正的客户端库,创建一个全栈集成测试。 可能的Mockito这里用来嘲笑客户无关的REST服务消费的部分。



Answer 4:

最好的方法是使用wiremock添加下面的依赖com.github.tomakehurst wiremock 2.4.1 org.igniterealtime.smack嫌核心4.0.6

定义和使用wiremock如下所示

@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);

String response ="Hello world";
StubMapping responseValid = stubFor(get(urlEqualTo(url)).withHeader("Content-Type", equalTo("application/json"))
        .willReturn(aResponse().withStatus(200)
                .withHeader("Content-Type", "application/json").withBody(response)));


Answer 5:

我同意这是不是单元测试,但集成测试,反正你宁愿看看球衣和嵌入式灰熊服务器测试。 为了萨姆起来,这个代码启动灰熊服务器在本地主机(可以启动datbase以及):8888,然后安装客户端的球衣的客户端和sents POST请求,响应应该进行测试。 这是一个整合,因为你同时测试服务器和数据库,你可以使用但是的Mockito来模拟数据库,但要看怎么绑你的服务器和数据库。

(使用的球衣1.11和篦条筛2.2试验)

    @BeforeClass
    public static void setUpClass() throws Exception {
        // starts grizzly
        Starter.start_grizzly(true);
        Thread.sleep(4000);
    }

    @Before
    public void setUp() throws Exception {
        client = new Client();
        webResource = client.resource("http://localhost:8888");
    }   

    @Test
    public void testPostSchemaDatabase() throws Exception {
        {
            String DatabaseSchema = "{ database_schema : {...}}";
            logger.info("REST client configured to send: "  + DatabaseSchema);
            ClientResponse response =  
                    webResource
                             .path("/initialize")
                             .type("application/json")
                             .post(ClientResponse.class, DatabaseSchema);
            //wait for the server to process
            Thread.sleep(2000);
            assertEquals(response.getStatus(), 204);    
            //test the response
        }       
    }

    @After
    public void after() throws JSONException
    {
            //probably you want to delete the schema at database and stop the server

}


文章来源: How to use mockito for testing a REST service?