Dropwizard测试 - javax.validation.ConstraintViolationException:请求实体为空

时间:2014-08-05 08:13:00

标签: rest maven junit jersey dropwizard

我正在使用Dropwizard 0.7编写REST服务的集成测试。我正在关注Dropwizard文档http://dropwizard.readthedocs.org/en/latest/manual/testing.html 我正在尝试使用io.dropwizard.testing库测试简单的get请求。

    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-testing</artifactId>
        <version>0.7.1</version>
    </dependency>

我的代码是:

@ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()    
        .addResource(new EvaluationResource()) 
        .build(); 

@Test
public void testGetPrompt() { 
    List<Class<?>> mappedClasses = config(); 
    HibernateUtil.init(ADeployer.DEPLOYMENT_DIR, "localhost", 3306, "stat", mappedClasses); 
    UserIdentity userIdentity = UserIdentityDAO.validate(new Long(1), "asdfasdf", "Slavina");
    String token = UserIdentityDAO.generateToken(userIdentity); 
    User user = userManager.getUser(token);

    resources.builder().setMapper(MAPPER);
    resources.client().resource("https://localhost:8080/execute/prompt?sessionKey=" + token).type(MediaType.APPLICATION_JSON).get(User.class);      
} 

我的方法是:

@GET
@Path("/prompt")
public String getPromptMessage(@SessionAuth User user) {
    try {
        Autosave status = user.getWorker().getStatus(user.getSessionKey());
        return status.getPendingPromptMessage();
    }
    catch (Exception e) {
        throw new RestException(e);
    }
}

我得到的是成功连接到db,我得到了正确的令牌,Exception是:

Test  c.s.j.s.c.ContainerResponse:419 [main] - The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
javax.validation.ConstraintViolationException: The request entity was empty
    at io.dropwizard.jersey.jackson.JacksonMessageBodyProvider.validate(JacksonMessageBodyProvider.java:70) ~[dropwizard-jersey-0.7.0.jar:0.7.0]
    at io.dropwizard.jersey.jackson.JacksonMessageBodyProvider.readFrom(JacksonMessageBodyProvider.java:60) ~[dropwizard-jersey-0.7.0.jar:0.7.0]
    at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:490) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:86) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:183) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) ~[jersey-server-1.18.1.jar:1.18.1]
    at io.dropwizard.jersey.guava.OptionalResourceMethodDispatchAdapter$OptionalRequestDispatcher.dispatch(OptionalResourceMethodDispatchAdapter.java:37) ~[dropwizard-jersey-0.7.0.jar:0.7.0]
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.uri.rules.ResourceObjectRule.accept(ResourceObjectRule.java:100) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) ~[jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542) [jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473) [jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419) [jersey-server-1.18.1.jar:1.18.1]
    at com.sun.jersey.test.framework.impl.container.inmemory.TestResourceClientHandler.handle(TestResourceClientHandler.java:119) [jersey-test-framework-inmemory-1.18.1.jar:1.18.1]
    at com.sun.jersey.api.client.Client.handle(Client.java:652) [jersey-client-1.18.1.jar:1.18.1]
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) [jersey-client-1.18.1.jar:1.18.1]
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) [jersey-client-1.18.1.jar:1.18.1]
    at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:509) [jersey-client-1.18.1.jar:1.18.1]
    at com.zh.backend.resources.PackageResourceTest.testGetPerson(PackageResourceTest.java:122) [test-classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_55]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_55]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_55]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_55]
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) [junit-4.11.jar:na]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) [junit-4.11.jar:na]
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) [junit-4.11.jar:na]
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) [junit-4.11.jar:na]
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) [junit-4.11.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) [junit-4.11.jar:na]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) [junit-4.11.jar:na]
    at io.dropwizard.testing.junit.ResourceTestRule$1.evaluate(ResourceTestRule.java:150) [dropwizard-testing-0.7.1.jar:0.7.1]
    at org.junit.rules.RunRules.evaluate(RunRules.java:20) [junit-4.11.jar:na]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) [junit-4.11.jar:na]
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) [.cp/:na]
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:na]

我肯定做错了传递参数,但我找不到什么,你能帮帮我吗?

1 个答案:

答案 0 :(得分:3)

我遇到了一个与此非常相似的问题,并且刚刚找到了解决方案,我希望这也会有所帮助。

在我的情况下,&#34; ConstraintViolationException的原因:请求实体在&#34;异常是因为在构造Resource mock时,它会遍历所有注释并将它们与它期望的注释映射进行比较。这些都不是@SessionAuth或@Auth(我正在使用),因此默认情况下它假定注释必须表示其相关参数是实体。在获取请求的情况下,不存在实体,因此它会爆炸。

解决方案似乎是在ResourceTestRule构建器中调用.addProvider,因此它可以查找对注释的理解。例如,我必须这样做:

    @Rule
        public final ResourceTestRule resources = ResourceTestRule.builder()
                .addResource(new GroupSuggestionsResourceV1(RANKING_STORE, CLIENT))
                .addProvider(new OAuthProvider<>(AUTHENTICATOR, "test-realm"))
                .build();

告诉资源构建器期望auth注释,并适当地处理它。最初我只是在做.addProvider(AUTHENTICATOR),但是没有用,所以如果你遇到麻烦,你可能想尝试两者。

我希望这可以帮助其他人解决这个问题!