您是否想要尽快且没有任何麻烦地测试您的睡觉应用编程接口?代码中可以进行测试的最早位置是在提交阶段,您可以在此阶段运行单元测试。我想为您介绍一种简单快捷的测试睡觉接口的方法。示例代码基于JUnit和RESTEasy。它不需要任何外部数据库或重量级应用程序服务器,这意味着您可以独立运行并开箱即用。
RESTEasy(和Jersey一样)在他们的库中包含一个最小的Web服务器,使他们的用户能够启动一个小型Web服务器,用于生产或运行测试。
TJWSEmbeddedJaxrsServer server = new TJWSEmbeddedJaxrsServer();
server.setPort("12345");
server.getDeployment().getResources().add(myResourceInstance);
// alternative
server.getDeployment().getProviderClasses().add("com.my.my.resource.class.name");
server.start();
new ResteasyClientBuilder().build().target("http://localhost:12345/myresource").request().get()
就这样。有些测试用例就是这么简单。其他测试用例需要更多功能,如动态端口(例如,当多个构建在同一台机器上运行时)、用于身份验证的安全域或您需要的一组提供程序类,以便编组/解组/转换异常。这些要求可能会导致每次测试中出现大量样本。我想提供一种更通用、更可重用的方法,用Junit和RESTEasy 3.0:
public class InMemoryRestTest {
@Path("myresource")
public static class MyResource {
@POST
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_XML)
public MyModel createMyModel(int number) {
return new MyModel(number);
}
}
public static MyResource sut = new MyResource();
public static InMemoryRestServer server;
@BeforeClass
public static void beforeClass() throws Exception {
server = InMemoryRestServer.create(sut);
}
@AfterClass
public static void afterClass() throws Exception {
server.close();
}
@Test
public void postSimpleBody() throws Exception {
Response response = server.newRequest("/myresource").request().buildPost(Entity.text("42")).invoke();
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
MyModel myModel = response.readEntity(MyModel.class);
assertEquals(42, myModel.getResult());
}
}
这个测试已经构建好了一切,可以提供睡觉应用编程接口并在一个单元中使用它。MyResource
是睡觉服务提供功能,RESTEasy客户端利用该接口。
所有引导和睡觉服务器设置都封装在InMemoryRestServer
这也为测试提供了一个方便的入口点。您不再需要在测试代码中处理端口号。你可以找到完整的代码here。
有时,您的代码依赖于位于其他类内或接口后面的其他服务或功能。通常,您会使用模拟来模拟该行为。所以让我们试一试。
@RunWith(MockitoJUnitRunner.class)
public class InMemoryRestWithMockitoTest {
public static interface BackendService {
MyModel getMyModel(int number);
}
@Path("myresource")
public static class MyResource {
private BackendService backendService;
@POST
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_XML)
public MyModel createMyModel(int number) {
return backendService.getMyModel(number);
}
}
@InjectMocks
public static MyResource sut = new MyResource();
public static InMemoryRestServer server;
@Mock
private BackendService backendServiceMock;
@BeforeClass
public static void beforeClass() throws Exception {
server = InMemoryRestServer.create(sut);
}
@AfterClass
public static void afterClass() throws Exception {
server.close();
}
@Test
public void postWithoutMocking() throws Exception {
Response response = server.newRequest("/myresource").request().buildPost(Entity.text("42")).invoke();
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
}
@Test
public void postWithMocking() throws Exception {
when(backendServiceMock.getMyModel(42)).thenReturn(new MyModel(42));
Response response = server.newRequest("/myresource").request().buildPost(Entity.text("42")).invoke();
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
MyModel myModel = response.readEntity(MyModel.class);
assertEquals(42, myModel.getResult());
}
}
这段代码并不比没有模仿的代码复杂多少。您可以使用您选择的模仿框架(这里我使用Mockito),将模拟注入您的睡觉应用编程接口服务并运行您的测试。您可以在上找到所有代码GitHub。