Reputation: 338306
The Assertions
class in JUnit 5 allows for passing an Supplier<String>
as a messageSupplier
, an object that provides the text of a message to report when the test fails.
For example, assertEquals
:
public static void assertEquals( char expected,
char actual,
Supplier<String> messageSupplier )
I am wondering what the practical use of such a supplier might be, specifically in the context of unit testing.
I can imagine perhaps localizing the strings, though that seems a bit strange to localize when the audience is the members of a development project.
➥ Are there any other practical uses of passing such a message supplier rather than hard-coding message string?
Upvotes: 9
Views: 3207
Reputation: 2635
Besides being useful when building the message is expensive, as already answered, I think another interesting and useful use-case is when the failure message can be constructed only in case of failure.
For example, let's say that you have an object as a result of one of your methods, and you expect that object to be null
. In case of failure you want to show a failure message with some information taken from the unexpected non-null object, e.g., by calling one of its methods:
MyEntity e = mySut.find(...);
assertNull(e, "Unexpected found entity with id: " + e.getId());
This test method will always throw a NullPointerException
when the test should succeed. In fact, the message string is always evaluated, being an argument of the assert method.
Instead of resorting to a more complex and involved solution, undermining the readability of your tests, like
MyEntity e = mySut.find(...);
String failureMessage = "";
if (e != null)
failureMessage = "Unexpected found entity with id: " + e.getId();
assertNull(e, failureMessage);
You can simply use the assert method with a message supplier:
MyEntity e = mySut.find(...);
assertNull(e, () -> "Unexpected found entity with id: " + e.getId());
Now, the body of the lambda will be executed only in case of failure, when the object used to create the message is surely not null
.
Upvotes: 11
Reputation: 5341
If I remember correctly, we - the JUnit 5 team - introduced the supplier variant for cases in which building the message string is costly, eg due to accessing a database. You’d only want to do this if necessary, ie in case of failure.
Upvotes: 11