在 JUnit 5 中将“供应商”作为消息供应商传递的选项的实际用途

Practical uses for the option to pass `Supplier` as a message supplier in JUnit 5

作为 messageSupplierAssertions class in JUnit 5 allows for passing an Supplier<String>,一个提供测试失败时要报告的消息文本的对象。

例如,assertEquals:

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

我想知道 这种供应商 的实际用途是什么,特别是在单元测试的情况下。

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

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

当构建消息很昂贵时

如果我没记错的话,我们 - JUnit 5 团队 - 针对构建消息字符串成本高昂的情况引入了供应商变体,例如由于访问数据库。你只会在必要时才这样做,即在失败的情况下。

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

除了在构建消息昂贵时有用之外,正如已经回答的那样,我认为另一个有趣且有用的 use-case 是何时可以构建失败消息仅在失败的情况下.

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

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

当测试应该成功时,此测试方法将始终抛出 NullPointerException。事实上,消息字符串 always 被评估,作为 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