用于Spring-Jersey应用程序的JerseyTest中的资源模型验证失败 [英] Resource model validation failure in JerseyTest for Spring-Jersey application

查看:862
本文介绍了用于Spring-Jersey应用程序的JerseyTest中的资源模型验证失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带注释的Spring-Jersey应用程序.我试图使用JerseyTest为我的控制器设置单元测试.我在运行无法弄清的测试时遇到以下错误.我错过了什么?

I have an annotated Spring-Jersey application. I am trying to set up unit test for my controllers using JerseyTest. I am getting the following errors on running the test that I am not able to figure out. What have I missed?

SEVERE: Following issues have been detected: 
WARNING: No injection source found for a parameter of type public com.example.services.dto.UnitDto com.example.apis.UnitResource.getUnits(com.example.services.dto.PointDto) throws com.example.exceptions.PointOutsideBounds at index 2.

Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public com.example.services.dto.UnitDto com.example.apis.UnitResource.getUnits(com.example.services.dto.PointDto) throws com.example.exceptions.PointOutsideBounds at index 2.; source='ResourceMethod{httpMethod=GET, consumedTypes=[], producedTypes=[application/json], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class com.example.apis.UnitResource, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@31a5870e]}, definitionMethod=public com.example.services.dto.UnitDto com.example.apis.UnitResource.getUnits(com.example.services.dto.PointDto) throws com.example.exceptions.PointOutsideBounds, parameters=[Parameter [type=class com.example.services.dto.PointDto, source=contains, defaultValue=null]], responseType=class com.example.services.dto.UnitDto}, nameBindings=[]}']
    at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:555)

控制器类如下:

@Component
@Path("/app/units")
public class UnitResource {
    @Context
    private UriInfo uriInfo;
    @Context
    private Request request;

    @Inject
    private UnitService unitService;

    @Inject
    public UnitResource(@Named("UnitService") UnitService unitService) {
        this.unitService = unitService;
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Timed(absolute = true, name = "getUnitForPoint")
    public UnitDto getUnits(@QueryParam("contains") @NotNull PointDto point) throws PointOutsideBounds {
        return unitService.getUnitForPoint(point);
    }
}

测试类如下:

public class UnitResourceTest extends JerseyTest {

    @Mock
    private UnitService unitService;

    @Override
    protected ResourceConfig configure() {
        ResourceConfig rc = new ResourceConfig()
        //      .register(new UnitResource(Mockito.mock(UnitService.class))) -- has the same effect
                .register(UnitResource.class)
                .property("contextConfig", new AnnotationConfigApplicationContext(ApplicationConfiguration.class));

        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);
        forceSet(TestProperties.CONTAINER_PORT, "0");

        return rc;
    }

    @Before
    public void setUp() throws Exception {
        super.setUp();
        initMocks(this);
    }

    @Override
    protected TestContainerFactory getTestContainerFactory() {
        return new InMemoryTestContainerFactory();
    }

    @Test
    public void testGetUnit() throws PointOutsideBounds {

        Response response = target()
                .path("/app/units")
                .queryParam("contains", new Point(0.0,0.0).toJson())
                .request(MediaType.APPLICATION_JSON_TYPE)
                .get();

        assertThat(response.getStatus(), is(Response.Status.OK));
    }
}

应用程序配置类为:

@Configuration
@ComponentScan("com.example")
public class ApplicationConfiguration {
    @Bean(name="UnitService")
    public UnitService unitService() {
        return new UnitService();
    }
}

我对Gradle的测试配置依赖性为:

My Gradle dependencies for test configuration are:

dependencies {
    // Using junit-dep package to get junit without hamcrest dependency
    testCompile("junit:junit-dep:4.8.2")
    testCompile("org.hamcrest:hamcrest-all:1.3")
    testCompile("org.mockito:mockito-all:1.8.4")
    testCompile ('org.glassfish.jersey.test-framework:jersey-test-framework-core:2.22.2')
    testCompile('org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-inmemory:2.22.2')
}

configurations {
    testCompile.exclude group: 'org.glassfish.jersey.ext', module: 'jersey-spring3'
}

我找到了 ,但都没有解决我的问题.

I found this and this but neither solved my problem.

推荐答案

注意:大多数情况下,此答案适用于所有带有@XxxParam注释的参数.

Note: For the most part, this answer applies to all @XxxParam annotated parameters.

PointDto参数似乎是问题所在

public UnitDto getUnits(@QueryParam("contains") @NotNull PointDto point)

查询参数是字符串. Jersey可以将String转换为一些基本类型,如intbooleanDate等.但是它不知道如何从该String创建PointDto.这并不意味着我们不能使用自定义类型.我们只需要遵循一些规则:

Query parameters are Strings. Jersey has the capability to convert that String to some basic types like int, boolean, Date, etc. But it has no idea how to create the PointDto from that String. That doesn't mean that we can't use custom types. We just need to follow some rules:

  1. 具有一个接受String的构造函数.然后,我们需要根据该字符串自己构造对象.例如

  1. Have a constructor that accepts a String. Then we need to construct the object ourselves from that String. For example

public PointDto(String param) {
    Map<String, Object> map = parseJson(param);
    this.field1 = map.get("field1");
    this.field2 = map.get("field2");
}

需要一些工作.

另一种选择是在类中具有静态fromString(String)或静态valueOf(String). Jersey将调用此方法来构造对象.例如,您可以在您的PointDto

Another option is to have a static fromString(String) or static valueOf(String) in the class. Jersey will invoke this method to construct the object. So for instance you can have in your PointDto class

public static PointDto fromString(String param) {
    PointDto dto = parseJson(param);
    return dto;
}

  • 您可以拥有一个ParamConverterProvider.我不会举一个例子,但是您可以在这篇文章

  • You can have a ParamConverterProvider. I won't put an example, but you can read more in this good article about how you can implement it. You can also see this post

    请注意,此答案中显示的信息在 @QueryParam .

    Note, the information presented in this answer is in the javadoc for @QueryParam.

    这篇关于用于Spring-Jersey应用程序的JerseyTest中的资源模型验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆