【问题标题】:Unit Testing StreamingOuput as Response entity Jersey单元测试 StreamingOutput 作为响应实体 Jersey
【发布时间】:2016-06-16 04:39:18
【问题描述】:

我正在做类似于中提到的事情 Example of using StreamingOutput as Response entity in Jersey

@GET
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response streamExample(@Context UriInfo uriInfo) {
  StreamingOutput stream = new StreamingOutput() {
    @Override
    public void write(OutputStream os) throws IOException,WebApplicationException {
    try{
      Writer writer = new BufferedWriter(new OutputStreamWriter(os));
      //Read resource from jar
      InputStream inputStream = getClass().getClassLoader().getResourceAsStream("public/" + uriInfo.getPath());

      ...//manipulate the inputstream and build string with StringBuilder here//.......
      String inputData = builder.toString();
      Writer writer = new BufferedWriter(new OutputStreamWriter(os));
      writer.write(inputData);
      writer.flush();
    } catch (ExceptionE1) {
        throw new WebApplicationException();
      }
    }
};
  return Response.ok(stream,MediaType.APPLICATION_OCTET_STREAM).build();
}

我正在尝试通过像How to get instance of javax.ws.rs.core.UriInfo 中提到的那样模拟 URIInfo 来对此进行单元测试

  public void testStreamExample() throws IOException, URISyntaxException {
        UriInfo mockUriInfo = mock(UriInfo.class);
        Mockito.when(mockUriInfo.getPath()).thenReturn("unusal-path");
        Response response = myresource.streamExample(mockUriInfo);}

当我将 jar 的路径切换到其他东西时,我希望能够检查我是否得到了一个异常。但是,当我运行/调试测试时,我从不进入

public void write(OutputStream os) throws IOException,
            WebApplicationException {...}

部分,我只打return Response.ok(stream,MediaType.APPLICATION_OCTET_STREAM).build();

我在这里遗漏了一些非常明显的东西吗?

【问题讨论】:

    标签: unit-testing jar jersey mockito junit4


    【解决方案1】:

    因为流在到达MessageBodyWriter(这是最终调用StreamingOutput#write 的组件)之前不会被写入。

    您可以做的就是从返回中获取Response 并调用Response#getEntity()(它返回一个对象)并将其转换为StreamingOutput。然后自己调用write方法,传递一个OutputStream,也许是一个ByteArrayOutputStream,这样你就可以得到一个byte[]的内容来检查它。这一切看起来都像

    UriInfo mockInfo = mockUriInfo();
    Response response = resource.streamExample(mockInfo);
    StreamingOutput output = (StreamingOutput) response.getEntity();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    output.write(baos);
    byte[] data = baos.toByteArray();
    String s = new String(data, StandardCharsets.UTF_8);
    assertThat(s, is("SomeCharacterData"));
    

    【讨论】:

    • 感谢您的回复。如果我理解正确,任何检查都会涉及我实际比较从输出字节数组派生的字符串和我实际期望的字符串。我的想法是抛出异常,因为我的内容会随着时间的推移而变化并且非常大。我想这不是现在的选择。
    • 但这是一个单元测试。结果永远不应该改变。只需使用一个带有 URI 的简单文本文件,然后使用文本文件的内容进行测试。
    • 您可以在您的测试资源中添加一个public 目录,流输出应该从那里获取文本文件。甚至可以通过配置属性使目录可配置。这就是我会做的
    • 这段代码有一个小错误,把output.toByteArray();替换成baos.toByteArray();
    猜你喜欢
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2022-07-31
    • 2023-04-09
    • 2022-01-20
    相关资源
    最近更新 更多