单位测试球衣休息与球衣测试框架

时间:2010-12-18 08:25:15

标签: unit-testing testing rest jersey

我正在使用jersey测试框架为我的休息调用(在泽西实现)编写单元测试,我得到一个IncompatibleClassChangeError,这真的令人困惑:

    Caused by: java.lang.IncompatibleClassChangeError: Class javax.ws.rs.core.Response$Status does not implement the requested interface javax.ws.rs.core.Response$StatusType
 at com.sun.jersey.spi.container.ContainerResponse.getStatus(ContainerResponse.java:548)
 at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.commitWrite(ContainerResponse.java:156)
 at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.write(ContainerResponse.java:133)
 at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
 at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
 at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
 at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
 at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
 at java.io.BufferedWriter.flush(BufferedWriter.java:236)
 at com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191)
 at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128)
 at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88)
 at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58)
 at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:299)
 at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1326)
 at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1239)
 at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1229)
 at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:420)
 at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:497)
 at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:684)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
 at com.sun.grizzly.http.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:188)
 ... 20 more

我的休息电话是这样的:

@GET
@Produces("application/json")
@Path("/test") 
public String test() {
    return "it works";
}

我的测试是这样的:

public class MyTest extends JerseyTest {

    public MyTest() {
        super("com.mypackage");
    }

    @Test
    public void test() throws IllegalArgumentException, IOException {
        WebResource webResource = resource();
        webResource.path("/test").accept("application/json").get(ClientResponse.class).toString();
    }
}

第二行抛出异常。那么我在这里做错了什么?我正在使用jersey 1.4和1.4用于球衣测试框架。任何帮助,将不胜感激。谢谢!

更新:我注意到如果我通过maven在命令行中运行测试将会通过,很奇怪。

3 个答案:

答案 0 :(得分:0)

不是你问题的答案,但无论如何我都要问它。我相信你已经简化了这个例子,但我并没有真正看到为此编写单元测试的重要性。看起来您正在测试框架而不是任何真正的应用程序逻辑。如果你的get请求调用某些规则来返回某种模型对象,只需将该代码包装在一个对象中并使用DI来注入它。

例如:

@GET
@Produces("application/json")
@Path("/movies") 
public List<Movie> catalog() {
    return this.rentalManager.findAll();
}

现在你可以使用一个无聊的旧JUnit测试,而不是处理任何框架问题。它是否测试了您班级中是否存在正确的注释?不是真的,但我怀疑它会在验收测试中被捕获,并且一旦编码就不会发生太大变化。

当然如果它真的困扰你那么你当然可以写一些类似的测试:

@Test
public void catalogSupportsGetRequests() {
     verifyMethodHasAnnotation(MyResource.class, "catalog", "GET");
}

@Test
public void catalogProducesJson() {
     verifyMethodHasAnnotation(MyResource.class, "catalog", "Produces", "application/json");
}

// You get the idea.

希望有所帮助! 布兰登

答案 1 :(得分:0)

您的方法返回一个字符串

@GET
@Produces("application/json")
@Path("/test") 
public String test() {
    return "it works";
}

所以你应该期待一个String.class

public class MyTest extends JerseyTest {

    public MyTest() {
        super("com.mypackage");
    }

    @Test
    public void test() throws IllegalArgumentException, IOException {
        WebResource webResource = resource();
        assertEquals("it works",webResource.path("/test").accept("application/json").get(String.class));
    }
}

答案 2 :(得分:0)

尝试更改Jersey测试的设置以覆盖配置:

    public class MyTest extends JerseyTest {

    @Override
    protected Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);

        MyResource service = new MyResource();
        ResourceConfig config = new ResourceConfig();
        config.register(service);        

        Map<String, Object> mapProps = new HashMap<>();      mapProps.put(ServerProperties.BV_SEND_ERROR_IN_RESPONSE,Boolean.TRUE);
        config.addProperties(mapProps);

        return config;
    }

    /**
     * expects HTTP 200 for valid request
     * @param l
     * @param expectedText
     */
    private void expectValidRequest(String expectedText) {     
        Response output = target("/test").request(MediaType.APPLICATION_JSON).get();

        Assert.assertTrue(output.getStatus() == HttpStatus.OK_200);             
        Assert.assertTrue(output.getHeaders().get("Content-Type").get(0).equals(MediaType.APPLICATION_JSON));
        String textBody = output.readEntity(String.class);              
        Assert.assertTrue(textBody.equals(expectedText));   
    }

    @Test
    public void test() throws IllegalArgumentException, IOException {
        String expectedText = "{\"name\": \"it works\"}";
        expectValidRequest(l, expectedText);  
    }
}

// your Client response class - sample
    class ClientResponse {
        public ClientResponse(String name) {
            super();
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }


// your web service
@GET
@Produces("application/json")
@Path("/test") 
public ClientResponse test() {
    return new ClientResponse("it works");
}