4

JUnit 5 中的Assertions类允许传递Supplier<String>as amessageSupplier对象,该对象提供测试失败时报告的消息文本。

例如assertEquals

public static void assertEquals​( char expected,
                                 char actual,
                                 Supplier<String> messageSupplier )

我想知道这样一个供应商的实际用途可能是什么,特别是在单元测试的背景下。

我可以想象也许本地化字符串,虽然当观众是开发项目的成员时本地化似乎有点奇怪。

➥ 除了硬编码消息字符串之外,传递这样的消息提供者还有其他实际用途吗?

4

2 回答 2

7

当构建消息很昂贵时

如果我没记错的话,我们 - JUnit 5 团队 - 在构建消息字符串成本高昂的情况下(例如由于访问数据库)引入了供应商变体。您只想在必要时执行此操作,即在失败的情况下。

于 2019-02-20T05:25:55.423 回答
2

只有在失败的情况下才能构建消息

除了在构建消息昂贵时有用之外,正如已经回答的那样,我认为另一个有趣且有用的用例是只有在失败的情况下才能构建失败消息。

例如,假设您有一个对象作为您的一种方法的结果,并且您希望该对象是null. 在失败的情况下,您希望显示一条失败消息,其中包含从意外的非空对象中获取的一些信息,例如,通过调用其方法之一:

MyEntity e = mySut.find(...);
assertNull(e, "Unexpected found entity with id: " + e.getId());

NullPointerException当测试应该成功时,这个测试方法总是会抛出一个。事实上,消息字符串总是被评估,作为 assert 方法的一个参数。而不是诉诸更复杂和复杂的解决方案,破坏测试的可读性,比如

MyEntity e = mySut.find(...);
String failureMessage = "";
if (e != null)
   failureMessage = "Unexpected found entity with id: " + e.getId();
assertNull(e, failureMessage);

您可以简单地将 assert 方法与消息供应商一起使用:

MyEntity e = mySut.find(...);
assertNull(e, () -> "Unexpected found entity with id: " + e.getId());

现在,只有在失败的情况下才会执行 lambda 的主体,而用于创建消息的对象肯定不是null.

于 2020-09-16T13:47:40.510 回答