我正在尝试为Dropwizard中部署的JAX-RS资源编写单元测试,但是却遇到了javax.ws.rs.ProcessingException。
我已经写下了尝试的代码。
下面的界面位于项目api文件夹结构中。
@Path("/doPostRequest")
public interface SomeResource {
@POST
@Consumes({ "application/json" })
@Produces({ "application/json" })
void checkAndDoPostRequest(
@Suspended SomeResponse response,
@Valid SomeDetailsClass someDetailsClassObject;
);
}
我有一个在项目结构的服务文件夹中实现此接口的类,如下所示。
public class SomeResourceImpl implements SomeResource {
private SomeProcessor someProcessor;
@Inject
public SomeResourceImpl(final
SomeProcessor someProcessor) {
this.someProcessor = someProcessor;
}
@Override
@RolesAllowed("read")
public void checkAndDoPostRequest(
SomeResponse response,
SomeDetailsClass someDetailsClassObject) {
response.resume(someProcessor.doProcess(someDetailsClassObject));
}
}
我以前通过扩展JerseyTest类并使用target方法向该端点发送请求来为端点编写单元测试。但是对于dropwizard,我并不完全确定。
而且,此端点需要两个对象,即,在上述接口中,“ checkAndDoPostRequest”方法需要两个对象,并且我不确定如何使用JerseyTest中的“ target”方法发送两个对象。
这是我尝试过的单元测试。
public class SomeResourceImplTest {
private ServiceLocator serviceLocator;
private static String final URL = "/doPostRequest";
@Rule
public ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new SomeResourceImpl())
.build();
@Test
public void testPostRequest() {
Client client = resources.client();
resources.getJerseyTest().target(URL).request()
.post(Entity.entity(buildDetailsObject(),
MediaType.APPLICATION_JSON_TYPE));
}
private SomeDetailsClass buildDetailsObject() {
//code to build this object;
}
}
当我尝试运行上述测试用例时,出现以下异常
javax.ws.rs.ProcessingException: Server-side request processing failed with an error.
at org.glassfish.jersey.test.inmemory.InMemoryConnector$InMemoryResponseWriter.failure(InMemoryConnector.java:167)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:509)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:334)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.test.inmemory.InMemoryConnector.apply(InMemoryConnector.java:275)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:343)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at io.dropwizard.testing.junit.ResourceTestRule$1.evaluate(ResourceTestRule.java:174)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:68)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:74)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: javax.ws.rs.ProcessingException: Attempt to suspend a connection of an asynchronous request failed in the underlying container.
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:328)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
... 49 more
我尝试在单元测试中附加“ async()”函数,如下所示
public void testPostRequest() {
Client client = resources.client();
resources.getJerseyTest().target(URL).request().async()
.post(Entity.entity(buildDetailsObject(),
MediaType.APPLICATION_JSON_TYPE));
}
但是上面的实现只是阻止了处理异常,但是不能正确运行测试,即请求没有到达端点。
有人可以帮忙吗?
我遇到了同样的问题。在这个Github问题中有一个解决方案。
看起来InMemoryConnector不支持可以挂起并且是异步的端点,因此需要一个新的测试容器。您可能需要试用Grizzly测试Web服务器。我能够将其换出并通过测试用例。
构建资源规则时,应使用以下行,当然还要添加Grizzly依赖项。
setTestContainerFactory(new GrizzlyWebTestContainerFactory())
本期中有代码示例和更多信息。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句