如何从 jax-rs 模拟 StreamingOutput

How to mock StreamingOutput from jax-rs

我有一个 class 可以将视频作为 mp4 文件发送给用户 (Http request/response) 我想用主要逻辑模拟方法来测试它。我的代码

public StreamingOutput videoAsStream(final String videoUrl) {
        try {
            final URL url = new URL(videoUrl);
            return output -> {
                try(final InputStream inputStream = url.openConnection().getInputStream()){
                    IOUtils.copy(inputStream,output);
                    output.close();
                }
            };
        } catch (final MalformedURLException e) {
            log.error("Url exception for url {}",videoUrl);
            throw new UncheckedIOException(e);
        }
    }

我用什么方法来模拟这个逻辑?

AFAIK,您不能使用 mockito 模拟 finalstatic methods/classes。你将不得不依赖 PowerMockito。我目前无法测试你的方法,但如果你想模拟 final/static,你可以这样做 首先,将 final/static 类 添加到 @PrepareForTest 然后

InputStream mockInputStream = Mockito.mock(InputStream.class);
OutputStream mockOutputStream = Mockito.mock(OutputStream.class);
PowerMockito.mockStatic(IOUtils.class);
Mockito.when(IOUtils.copy(mockInputStream, mockOutputStream)).thenReturn(1L);
Mockito.doNothing().when(mockOutputStream).close();

如果这对您不起作用,请告诉我。

问题是,URL 是最终的,所以你必须至少使用 Mockito 2 来模拟它。如果您准备好这样做,我看到两种可能性:

a) 将 url 赋给方法而不是字符串,这样您就可以在其中放置一个模拟的 url。那将是最简单的方法。然后,您还可以创建第二个便捷方法,该方法从字符串创建 said URL 。这两种方法将更容易测试,因为它们的范围更小。

b) 将 final URL url = new URL(videoUrl); 部分提取到新的 class 中,例如 URL 工厂,然后将其模拟为 return 模拟的 URL测试中的对象。

一旦您在方法中使用 "new" 生成内容,此方法就会变得更难测试,因为您现在无法将此测试与此对象生成分开。