如何使用Mockito测试REST服务? [英] How to use mockito for testing a REST service?
问题描述
我对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屋!