在 JUnit 5 中将 `Supplier` 作为消息提供者传递的选项的实际用途

Bas*_*que 4 junit message junit5 junit-jupiter supplier

AssertionsJUnit 5 中的类允许传递Supplier<String>as a messageSupplier,这是一个提供消息文本以在测试失败时报告的对象。

例如assertEquals

public static void assertEquals?( char expected,
                                 char actual,
                                 Supplier<String> messageSupplier )
Run Code Online (Sandbox Code Playgroud)

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

我可以想象可能会对字符串进行本地化,尽管当受众是开发项目的成员时,本地化似乎有点奇怪。

? 传递这样的消息提供者而不是硬编码消息字符串还有其他实际用途吗?

lor*_*ini 8

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

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

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

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

NullPointerException当测试应该成功时,此测试方法将始终抛出 a 。事实上,消息字符串总是被评估,作为断言方法的参数。不要诉诸更复杂和更复杂的解决方案,而是破坏测试的可读性,例如

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

您可以简单地将断言方法与消息提供者一起使用:

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

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


joh*_*ink 7

当构建消息很昂贵时

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