您可以向AssertJ assertThat添加自定义消息吗?

我们有一个测试套件,主要使用带有Hamcrest匹配器的JUnit断言。 我们的一个团队开始对AssertJ进行实验,并以其语法,灵活性和声明性给人留下了深刻的印象。 JUnit提供的一项功能是我无法在AssertJ中找到与之等效的功能:添加自定义断言失败消息。

我们经常在比较不是为了人类可读性而制成的对象,这些对象将具有随机查找的Id或UUID,并且无法通过包含的数据来判断它们应该是什么。 不幸的是,对于我们的代码库来说,这是不可避免的情况,因为它实现的目的之一就是在其他服务之间映射数据而不必了解它是什么。

在JUnit中,assertThat方法在Matcher<T>参数之前提供了带有static assertThat参数的版本。 这使得添加简短的调试字符串变得轻而易举,从而使人们对问题有所了解,例如,比较对人类意味着什么。

另一方面,AssertJ提供了十亿种不同的通用static assertThat方法,这些方法返回某种形式的接口Assert或其许多实现类之一。 此接口不提供设置失败时包含的自定义消息的标准方法。

有什么方法可以从AssertJ API或其扩展之一中获取此功能,而不必为要向其添加消息的每个断言类型创建自定义断言类?

Patrick M asked 2019-10-09T10:17:11Z
3个解决方案
101 votes

以经典的方式,发布问题后,我发现了自己想要的片刻。 希望这将使下一个人更容易找到,而无需首先知道它的名字。 魔术方法是欺骗性的短名称as,它是as实现的另一个接口的一部分:可描述的,而不是基本的Assert接口。

as

设置支持as语法的此对象的描述。
范例:

as

如果断言失败,则在catch块as中带引号的字符串将出现在单元测试输出日志中。


我通过注意到问题中链接的自定义断言页面中的as帮助器发现了这一点。 该方法的JavaDoc指出它是受保护的,因此调用者不能使用它来设置自定义消息。 但是确实提到了overridingErrorMessage(String, Object...)助手:

此外,此方法支持使用as设置的任何描述或用户使用overridingErrorMessage(String, Object...)定义的替代错误消息。

...以及overridingErrorMessage帮助程序,该帮助程序使用提供的新字符串完全替换了标准AssertJ as消息。

直到功能突出显示页面为止,AssertJ主页都没有提到任何一个帮助程序,该页面在“软断言”部分显示了as帮助程序的示例,但是没有直接描述它的作用。

Patrick M answered 2019-10-09T10:18:18Z
2 votes

仅供参考,这在新的AssertJ网站(仍在建设中,但已经有有用的信息)中有记录,请参阅[https://assertj.github.io/doc/#assertj-core-assertion-description。]

Joel Costigliola answered 2019-10-09T10:18:44Z
2 votes

要为Patrick M的答案添加另一个选项:

除了使用Descriptable.as,您还可以使用Descriptable.as

try {
  // set a bad age to Mr Frodo which is really 33 years old.
  frodo.setAge(50);
  // you can specify a test description via withFailMessage(), supports String format args
  assertThat(frodo.getAge()).
    withFailMessage("Frodo's age is wrong: %s years, difference %s years",
      frodo.getAge(), frodo.getAge()-33).
    isEqualTo(33);
} catch (AssertionError e) {
  assertThat(e).hasMessage("Frodo's age is wrong: 50 years, difference 17 years");
}

使用Descriptable.as的不同之处在于,它使您可以完全控制自定义消息-没有“预期”和“但是”。

如果要测试的实际值不能用于表示,这将很有用-此方法使您可以显示其他可能计算出的值,或者完全不显示。


请注意,就像Descriptable.as一样,您必须在任何实际的断言之前调用withFailMessage()-否则它将不起作用,因为该断言将首先触发。 Javadoc中对此进行了说明。

sleske answered 2019-10-09T10:19:35Z
translate from https://stackoverflow.com:/questions/28994316/can-you-add-a-custom-message-to-assertj-assertthat