如何使用Mockito测试REST服务? [英] How to use mockito for testing a REST service?

查看:193
本文介绍了如何使用Mockito测试REST服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Java单元测试非常陌生,听说Mockito框架真的非常适合测试.

I am very new in Java Unit Testing and I heard that Mockito framework is really good for testing purposes.

我已经开发了REST服务器(CRUD方法),现在我想对其进行测试,但是我不知道如何?

I have developed a REST Server (CRUD methods) and now I want to test it, but I don't know how?

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

Even more I don't know how this testing procedure should begin. My server should work on localhost and then make calls on that url(e.g. localhost:8888)?

这是我到目前为止尝试过的方法,但是我很确定这不是正确的方法.

Here is what I tried so far, but I'm pretty sure that this isn't the right way.

    @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).如果一切顺利,则服务器应回答您的架构已成功创建!".

In this test case I want to send a Json string to the server(POST). If everything went well then the server should reply with "Your schema was succesfully created!".

有人可以帮我吗?

推荐答案

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

OK. So, the contract of the method is the following: Parse the input string as JSON, and send back BAD_REQUEST if it's invalid. If it's valid, create an entity in the datastore with various properties (you know them), and send back OK.

并且您需要验证该方法是否履行了该合同.

And you need to verify that this contract is fulfilled by the method.

Mockito在何处提供帮助?好吧,如果您在没有Mockito的情况下测试此方法,则需要一个真实的DataStoreService,并且需要验证是否已在该真实的DataStoreService中正确创建了该实体.这是您的测试不再是单元测试的地方,这也是测试太复杂,太长且难以运行的原因,因为它需要一个复杂的环境.

Where does Mockito help here? Well, if you test this method without Mockito, you need a real DataStoreService, and you need to verify that the entity has been created correctly in this real DataStoreService. This is where your test is not a unit test anymore, and this is also where it's too complex to test, too long, and too hard to run because it needs a complex environment.

Mockito可以通过模拟DataStoreService的依赖关系来提供帮助:您可以创建DataStoreService的模拟,并在测试中调用initialize()方法时验证是否使用适当的实体参数调用了该模拟

Mockito can help by mocking the dependency on the DataStoreService: you can create a mock of DataStoreService, and verify that this mock is indeed called with the appropriate entity argument when you call your initialize() method in your test.

为此,您需要能够将DataStoreService注入到被测对象中.可以通过以下方式重构对象一样简单:

To do that, you need to be able to inject the DataStoreService into your object under test. It can be as easy as refactoring your object in the following way:

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
    }
}

现在,在您的测试方法中,您可以执行以下操作:

And now in your test method, you can do:

@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
}

这篇关于如何使用Mockito测试REST服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆