【问题标题】:JUnit Test for expected exception fails despite throwing the same exception尽管抛出了相同的异常,但预期异常的 JUnit 测试失败
【发布时间】:2017-10-28 00:25:41
【问题描述】:

我已经通过 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)

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

【问题讨论】:

    标签: java spring-boot unit-testing junit


    【解决方案1】:

    好吧,我觉得有点傻,因为我刚刚在发布此消息后就解决了自己的问题。我没有仔细检查堆栈跟踪:

    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()。在我的问题中,我已将代码发布到 readStream(),因为我直观地知道这是引发异常的地方。

    但是,由于异常会沿堆栈向下传播到 convertStreamToString(),因此我从不抛出异常。我只打印堆栈跟踪。所以它卡在那个方法上,因此单元测试,它“监听”来自 convertStreamToString() 的 IOException,永远不会得到抛出的异常!

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

    【讨论】:

      猜你喜欢
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      相关资源
      最近更新 更多