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

问题描述 投票:0回答:2

考虑我有一个方法来测试,哪个

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

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

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();

Question 1

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

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

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

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

还有更好的选择吗?

Question 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;
}

- 但更优雅的版本非常受欢迎。

java unit-testing assertj
2个回答
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:您可以使用assertThatThrownBy

softly.assertThatThrownBy(() -> doSmth())
    .isInstanceOf(Exception.class)
    .hasMessage("My Message");
© www.soinside.com 2019 - 2024. All rights reserved.