如何编写junit测试用例来测试outofmemory错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何编写junit测试用例来测试outofmemory错误相关的知识,希望对你有一定的参考价值。

我最近在接受采访时被问到如何编写一个junit单元测试用例来测试“OutOfMemoryError”,我编写了以下代码: -

public class OutOfMemoryError {
    public static void main(String[] args) {
        new OutOfMemoryError().throwError();
    }

    public void throwError() {
        List<String> list = new ArrayList<>();
        for (int i = 0;; i++)
            list.add("1");
    }
}

Junit测试案例: -

public class ExceptionTest {
    private OutOfMemoryError outOfMemoryError;

    @Before
    public void init() {
        outOfMemoryError = new OutOfMemoryError();
    }

    @After
    public void tearDown() {
        outOfMemoryError = null;
    }


    @Test(expected = Error.class)
    public void testError() {
        outOfMemoryError.throwError();
    }
}

采访者告诉我,Junit测试用例不正确。任何人都可以告诉我正确的写作方式吗?

答案

JUnit可能无法正确处理由OutOfMemoryErrror引起的测试失败,因为JUnit本身需要(很少但不是没有)堆内存来处理失败。

不幸的是,在Throwable处理程序启动之前,JUnit不会释放对被测对象的引用(仍然在Statement对象中引用),所以即使垃圾收集也无法帮助。查看发生这种情况的ParentRunner.runLeaf的来源:

    } catch (Throwable e) {
        eachNotifier.addFailure(e);

然后EachTestNotifier.addFailure

    notifier.fireTestFailure(new Failure(description, targetException));

如果没有剩余堆内存,Failure::new将抛出另一个错误,阻止正确的测试失败处理。

回到采访:采访者可能想听说使用JUnit使用JUnit测试OutOfMemoryErrors是不可能的(可靠的),因为JUnit框架并没有像上面解释的那样设计那样做。面试可能也想看到类似的解决方法

@Test(expected = Error.class)
public void testError() {
    byte[] memoryRequiredByJUnitHandler = new byte[100_000];
    try {
        outOfMemoryError.throwError();
    } catch (Throwable t) {
        // free enough heap memory so JUnit can handle exception
        memoryRequiredByJUnitHandler = null;
        throw t;
    }
}

有关更多背景信息,您可能还想查看this answer to "When to catch java.lang.Error?"

以上是关于如何编写junit测试用例来测试outofmemory错误的主要内容,如果未能解决你的问题,请参考以下文章

spring-integration-file 的 junit 测试用例

如何编写测试用例来覆盖承诺链中所有嵌套的“then”回调

在Maven项目中运行JUnit 5测试用例

当我们有 rowmapper 时,如何使用 mockito 编写 junit 测试用例?

如何使用 junit 为 JPA REST API 编写测试用例?

如何使用 Junit 5 编写具有 System.exit() 的测试用例方法?