延迟抛出的异常以添加软断言

时间:2018-03-01 13:13:04

标签: java unit-testing assertj

考虑我有一个测试方法,

  • 可能有副作用(如在文件系统上创建的文件)和
  • 可能会抛出异常。

即使抛出异常,也可以观察(和测试)一些副作用。我的示例测试代码如下:

final SoftAssertions softly = new SoftAssertions();

try {
    /*
     * May throw an exception
     */ 
    doSmth();
} catch (final IOException ioe) {
    /*
     * How do I add a soft assertion wrapping an exception?
     */ 
}

/*
 * Testing for side effects.
 */
softly.assertThat(...).as("%s exit code", ...).isEqualTo(0);
softly.assertThat(...).as("the number of downloaded files").isEqualTo(3);
softly.assertThat(...).as("this should be true").isTrue();
softly.assertThat(...).as("and this should be true, too").isTrue();

softly.assertAll();

问题1

从抛出的异常中创建另一个软断言的最佳方法是什么?使用原始 TestNG API,我可以简单地编写

softly.fail(ioe.toString(), ioe);

AssertJ 似乎没有提供类似的东西。到目前为止,我最好的选择是将这样的smth添加到catch块:

softly.assertThat(true).as(ioe.toString()).isFalse();

还有更好的选择吗?

问题2

如何通过我的代码测试引发异常,显示为结果AssertionError的原因(或抑制异常)?目前,我执行以下操作:

Throwable failure = null;
try {
    doSmth();
} catch (final IOException ioe) {
    failure = ioe;
}

try {
    softly.assertAll();
} catch (final AssertionError ae) {
    if (failure != null) {
        if (ae.getCause() == null) {
            ae.initCause(failure);
        } else {
            ae.addSuppressed(failure);
        }
    }
    throw ae;
}

- 非常感谢更优雅的版本。

2 个答案:

答案 0 :(得分:3)

问题1 Xaero建议工作正常。

要解决这两个问题,请尝试使用catchThrowable结合fail(String failureMessage, Throwable realCause)(或one for soft assertions)。

如果你捕获了一个非null throwable(这意味着被测试的代码确实抛出异常),那么你可以使用fail构建一个带有自定义错误消息的AssertionError并传递被捕获的异常是AssertionError

的原因

代码如下:

Throwable thrown = catchThrowable(() -> { doSmth(); });

if (thrown != null) {
  softly.fail("boom!", thrown);
} else {
  softly.assertThat(...).as("%s exit code", ...).isZero();
  softly.assertThat(...).as("the number of downloaded files").isEqualTo(3);
  softly.assertThat(...).as("this should be true").isTrue();
  softly.assertThat(...).as("and this should be true, too").isTrue();
}

上面的代码让我感到有点不舒服,因为它测试了两种不同的场景,一种是在抛出异常时,另一种是在没有异常的情况下。创建两个测试用例可能是一个好主意,这将简化测试和断言部分(我相信)。

无论如何,希望它有所帮助!

ps:请注意,您可以使用isZero()代替isEqualTo(0)

答案 1 :(得分:1)

问题1 :您可以使用assertThatThrownBy

softly.assertThatThrownBy(() -> doSmth())
    .isInstanceOf(Exception.class)
    .hasMessage("My Message");