单元测试 StreamingOuput 作为响应实体 Jersey

dar*_*vil 3 unit-testing jar jersey junit4 mockito

我正在做类似于在泽西岛使用 StreamingOutput 作为响应实体的示例中提到的事情

@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();
}
Run Code Online (Sandbox Code Playgroud)

我试图通过模拟 URIInfo 来对此进行单元测试,如How to get instance of javax.ws.rs.core.UriInfo 中提到

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

当我将 jar 的路径切换到其他路径时,我希望能够检查是否收到异常。但是,当我运行/调试测试时,我从不输入

public void write(OutputStream os) throws IOException,
            WebApplicationException {...}
Run Code Online (Sandbox Code Playgroud)

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

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

Pau*_*tha 9

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

您可以做的就是Response从返回和调用Response#getEntity()(返回一个对象)中获取 并将其强制转换为StreamingOutput. 然后write自己调用该方法,传递一个OutputStream,也许是 aByteArrayOutputStream以便您可以将内容作为 abyte[]进行检查。这一切看起来像

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"));
Run Code Online (Sandbox Code Playgroud)

  • 这段代码有一个小错误,将 `output.toByteArray();` 替换为 `baos.toByteArray();` (2认同)