【问题标题】:unit test jersey rest call with jersey test framework使用球衣测试框架进行单元测试球衣休息调用
【发布时间】:2011-05-27 12:17:03
【问题描述】:

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

原因:java.lang.IncompatibleClassChangeError:类 javax.ws.rs.core.Response$Status 未实现请求的接口 javax.ws.rs.core.Response$StatusType 在 com.sun.jersey.spi.container.ContainerResponse.getStatus(ContainerResponse.java:548) 在 com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.commitWrite(ContainerResponse.java:156) 在 com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.write(ContainerResponse.java:133) 在 sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202) 在 sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272) 在 sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276) 在 sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122) 在 java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212) 在 java.io.BufferedWriter.flush(BufferedWriter.java:236) 在 com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191) 在 com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128) 在 com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88) 在 com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58) 在 com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:299) 在 com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1326) 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1239) 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1229) 在 com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:420) 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:497) 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:684) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:820) 在 com.sun.grizzly.http.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:188) ... 20 更多

我的休息电话是这样的:

@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 作为 jersey 测试框架。任何帮助,将不胜感激。谢谢!

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

【问题讨论】:

  • 在向我的应用程序(通过 org.springframework.web.filter.DelegatingFilterProxy)添加 Servlet 过滤器后,我似乎遇到了这个异常,过滤器将标头添加到 HttpServletResponse。

标签: unit-testing testing rest jersey


【解决方案1】:

不是你的问题的真正答案,但无论如何我必须问它。我确定您已经简化了示例,但我认为为此编写单元测试并没有多大价值。似乎您正在测试框架而不是任何真正的应用程序逻辑。如果您的 get 请求调用一些规则来返回某种模型对象,只需将该代码包装在一个对象中并使用 DI 注入它。

例如:

@得到 @Produces("应用程序/json") @Path("/电影") 公共列表目录(){ 返回 this.rentalManager.findAll(); }

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

当然,如果它真的让你感到困扰,那么你当然可以编写某种测试,例如:

@测试 公共无效目录支持GetRequests(){ verifyMethodHasAnnotation(MyResource.class, "catalog", "GET"); } @测试 公共无效目录ProducesJson(){ verifyMethodHasAnnotation(MyResource.class, "catalog", "Produces", "application/json"); } // 你明白了。

希望对您有所帮助! 布兰登

【讨论】:

    【解决方案2】:

    你的方法返回一个字符串

    @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));
        }
    }
    

    【讨论】:

      【解决方案3】:

      尝试更改 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");
      }
      

      【讨论】:

        猜你喜欢
        • 2014-02-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多