java - 尽管抛出相同的异常,但预期异常的 JUnit 测试仍失败

标签 java spring-boot unit-testing junit

我已经在 StackOverflow 上搜索了相同类型的问题,并检查了每个回复,但仍然面临这个问题。我正在测试从名为 readStream() 的方法抛出 IOException,该方法确实抛出 IOException,但 Junit 失败了使用 AssertionException 进行测试。

private static StringBuilder readStream(InputStream inputStream) throws IOException {

    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder stringBuilder = new StringBuilder();

    String line;

    try {
        while ((line = reader.readLine()) != null){
            stringBuilder.append(line + "\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
        throw e;
    }
   finally {
        try{
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return stringBuilder;
}

这是我的单元测试:

@SpringBootTest(classes = RequestResponseUtility.class)
public class RequestResponseUtilityTest extends AbstractTest {

    @Mock
    private InputStream inputStream;

    @Test(expected = IOException.class)
    public void convertStreamToStringNullTest() throws IOException {

        RequestResponseUtility.convertStreamToString(inputStream);
    }
}

正如您所见,我尝试让原始类中的异常实际抛出异常,而不是仅仅捕获并打印堆栈跟踪:

    e.printStackTrace();
    throw e;

我还尝试使用注释@Test(expected=IOException.class)和使用@Rule方法。两人都未能通过测试。我尝试使用 @SpringBootTest (如上所示)和 @RunWith(springjunit4classrunner.class) 注释我的测试。我真的很不知所措。我收到此错误

java.lang.AssertionError: Expected exception: java.io.IOException

但是我的堆栈跟踪是

java.io.IOException: Underlying input stream returned zero bytes
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:288)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at main.java.utilities.RequestResponseUtility.readStream(RequestResponseUtility.java:25)
    at main.java.utilities.RequestResponseUtility.convertStreamToString(RequestResponseUtility.java:45)

这让我心碎。这不是什么大问题,也不会影响我的代码在生产中的性能,但我想了解为什么会发生这种情况。

最佳答案

嗯,我觉得有点傻,因为我在发布这篇文章后就解决了自己的问题。我没有足够仔细地检查堆栈跟踪:

at main.java.utilities.RequestResponseUtility.readStream(RequestResponseUtility.java:25)
        at main.java.utilities.RequestResponseUtility.convertStreamToString(RequestResponseUtility.java:45)
        at test.java.utilities.RequestResponseUtilityTest.convertStreamToStringNullTest(RequestResponseUtilityTest.java:42)

调用的第一个方法是 convertStreamToStringNullTest(),我的单元测试。这会调用convertStreamToString()。然而,convertStreamToString()实际上在我的RequestResponseUtility类中调用了一个名为readStream()的私有(private)帮助器方法。在我的问题中,我已将代码发布到 readStream(),因为我凭直觉知道这就是抛出异常的地方。

但是,当异常沿着堆栈传播回 convertStreamToString() 时,我从不抛出异常。我只打印堆栈跟踪。因此它陷入了该方法,因此单元测试(即“监听”来自 convertStreamToString()IOException)永远不会得到抛出的异常!

这个故事的寓意是检查嵌套方法并真正跟踪异常应该来自哪里!

关于java - 尽管抛出相同的异常,但预期异常的 JUnit 测试仍失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44212928/

相关文章:

java - 为什么我的java动画占用了我的整个CPU

spring - 替换 spring-data Page 的全部内容,同时保持分页信息

visual-studio - 使用自定义程序集基目录从命令行运行 MsTest

javascript - 难以 mock Promise.all

java - 从 java 应用程序在 wso2is 上使用 openid 登录

java - 网络驱动程序。使用参数化类后无法运行测试

java - Java 中的消息格式以及如何在 Golang 中复制相同的格式

java - 如何在flyway中使用自定义sql脚本位置?

java - Hibernate Search - 即使 Elasticsearch 集群关闭也启动应用程序

java - 如何在 Spring Boot 中注入(inject) Clock.getInstance()?