3

我正在使用 Jersey 版本 2.23.2,但我无法弄清楚如何JerseyTest在验证失败时测试响应。出于某种原因,下面的测试会抛出一个ConstraintViolationException包裹在 a 中的 aProcessingException而不是返回400Bad Request。我可以修改测试以检查是否ProcessingException被抛出,但我真的想测试响应。当我在没有 的HelloResource情况下在 Grizzly 中运行时JerseyTest,我会得到适当的400错误请求响应。关于如何修复以下badRequestResponse()测试的任何想法?

package example;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;

import static org.junit.Assert.assertEquals;

public class BadRequestTest extends JerseyTest {
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Hello {
        @NotNull(message = "Name is a required field.")
        private final String name;

        private Hello() {
            this(null);
        }

        public Hello(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    @Path("hello")
    public static class HelloResource {
        @POST
        public String sayHelloToMe(@Valid Hello hello) {
            return "Hello " + hello.getName() + "!";
        }
    }

    @Override
    protected Application configure() {
        return new ResourceConfig(HelloResource.class).property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
    }

    /** Test OK Response. This Works!*/
    @Test
    public void okResponse() {
        Response response = target("hello")
                .request(MediaType.TEXT_PLAIN)
                .post(Entity.json(new Hello("Tiny Tim")));

        assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
        assertEquals("Hello Tiny Tim!", response.readEntity(String.class));
    }

    /** Test Bad Request Response.  This Fails! */
    @Test
    public void badRequestResponse() {
        Response response = target("hello")
                .request(MediaType.TEXT_PLAIN)
                .post(Entity.json(new Hello(null)));

        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
    }
}

这是我得到的例外:

javax.ws.rs.ProcessingException: 
Exception Description: Constraints violated on marshalled bean:
example.BadRequestTest$Hello@456abb66
-->Violated constraint on property name: "Name is a required field.".
Internal Exception: javax.validation.ConstraintViolationException

    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:261)
    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 example.BadRequestTest.badRequestResponse(BadRequestTest.java:70)
    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 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    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.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: Exception [EclipseLink-7510] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.BeanValidationException
Exception Description: Constraints violated on marshalled bean:
example.BadRequestTest$Hello@456abb66
-->Violated constraint on property name: "Name is a required field.".
Internal Exception: javax.validation.ConstraintViolationException
    at org.eclipse.persistence.exceptions.BeanValidationException.constraintViolation(BeanValidationException.java:53)
    at org.eclipse.persistence.jaxb.JAXBBeanValidator.buildConstraintViolationException(JAXBBeanValidator.java:385)
    at org.eclipse.persistence.jaxb.JAXBBeanValidator.validate(JAXBBeanValidator.java:273)
    at org.eclipse.persistence.jaxb.JAXBMarshaller.validateAndTransformIfNeeded(JAXBMarshaller.java:588)
    at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:481)
    at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:949)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
    at org.glassfish.jersey.client.ClientRequest.doWriteEntity(ClientRequest.java:517)
    at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:499)
    at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:388)
    at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:252)
    ... 39 more
Caused by: javax.validation.ConstraintViolationException
    at org.eclipse.persistence.jaxb.JAXBBeanValidator.buildConstraintViolationException(JAXBBeanValidator.java:383)
    ... 52 more
4

1 回答 1

2

这是一个客户端问题。正如您所发现的那样,MOXy 默认启用了 bean 验证。因此,您正在客户端上进行 bean 验证。因此,由于客户端发生错误,因此请求甚至没有通过。你可以通过发送一个字符串来测试它

Entity.json("{}")

那应该摆脱错误。但是,如果您想使用 bean,正如您在评论中提到的,您应该使用 MOXy 在客户端禁用 bean 验证

@Override 
protected void configureClient(final ClientConfig config) {  
    super.configureClient(config);
    config.register(new MoxyJsonConfig() 
            .property(MarshallerProperties.BEAN_VALIDATION_MODE,
                      BeanValidationMode.NONE).resolver());
}
于 2016-10-18T14:43:27.290 回答