我正在使用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在命令行中运行测试将会通过,很奇怪。
答案 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");
}