如何使用google-truth测试是否正在抛出预期的异常?

2022-09-01 23:07:46

我只想测试是否使用google-truth抛出具有给定消息的异常。

使用 junit using 很容易做到这一点,但我无法弄清楚如何用真理来做到这一点。ThrowableSubject周围没有样本。@Test(expected=

我应该坚持使用普通进行此类测试吗?JUnit


答案 1

[已更新]

Truth的作者建议使用JUnit 4.13 / 5的机制,因为这在Truth中并不需要支持。这看起来更像:assertThrows()

SpecificException e = 
    assertThrows(SpecificException.class, () -> doSomethingThatThrows());
assertThat(e).hasMessageThat().contains("blah blah blah");
assertThat(e).hasCauseThat().isInstanceOf(IllegalStateException.class);
assertThat(e).hasCauseThat().hasMessageThat().contains("blah");

建议使用 try/fail/catch,因为它更简洁,避免了“缺少失败”问题,并返回一个可以使用 in Truth 断言的对象。ThrowableSubject

如果没有 ,请使用 try/fail/catch 模式,因为这是清晰而明确的。assertThrows()

try {
  doSomethingThatThrows(); 
  fail("method should throw");
} catch (SpecificException e) {
  // ensure that e was thrown from the right code-path
  // especially important if it's something as frequent
  // as an IllegalArgumentException, etc.
  assertThat(e).hasMessage("blah blah blah");
}

虽然存在JUnit中,但Truth团队并不推荐这些测试,因为它们有一些微妙(和不那么微妙)的方式,你可以编写通过但应该失败的测试。@Rule ExpectedException@Test(exception=...)

虽然try/fail/catch也是如此,但Google内部通过使用容易出错来缓解这种情况,它提供了静态编译时检查,以确保此模式不会省略fail()等。强烈建议您使用容易出错的检查或其他静态分析检查来捕获这些内容。可悲的是,基于规则和基于注释的方法并不像这个 try/catch 块那样容易适应静态分析。


答案 2

作为这里的更新,我们已经摆脱了Christian描述的模式,并且问题#219已经关闭,转而支持JUnit的expecentThrows()(在4.13中,类似的方法已经存在于TestNG的Assert中)。

同时,您可以使用 Truth 对抛出的异常进行断言。所以克里斯蒂安的例子现在是:expectThrows()

SpecificException expected = expectThrows(
    SpecificException.class, () -> doSomethingThatThrows());
assertThat(expected).hasMessageThat().contains("blah blah blah");

推荐