We have a test suite that primarily uses JUnit assertions with Hamcrest matchers. One of our team started experimenting with AssertJ and impressed people with its syntax, fl
FYI this is documented in the new AssertJ website, see https://assertj.github.io/doc/#assertj-core-assertion-description.
To add another option to Patrick M's answer:
Instead of using Descriptable.as
, you can also use AbstractAssert.withFailMessage():
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");
}
The difference to using Descriptable.as
is that it gives you complete control over the custom message - there is no "expected" and "but was".
This is useful where the actual values being tested are not useful for presentation - this method allows you to show other, possibly calculated values instead, or none at all.
Do note that, just like Descriptable.as
, you must call withFailMessage()
before any actual assertions - otherwise it will not work, as the assertion will fire first. This is noted in the Javadoc.
And in classic fashion, I found what I was looking for moments after posting the question. Hopefully this will make it easier for the next person to find without first having to know what it's called. The magic method is the deceptively short-named as, which is part of another interface that AbstractAssert
implements: Descriptable, not the base Assert interface.
public S as(String description, Object... args)
Sets the description of this object supporting
String.format(String, Object...)
syntax.
Example :try { // set a bad age to Mr Frodo which is really 33 years old. frodo.setAge(50); // you can specify a test description with as() method or describedAs(), it supports String format args assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33); } catch (AssertionError e) { assertThat(e).hasMessage("[check Frodo's age] expected:<[33]> but was:<[50]>"); }
Where that quoted string in the catch block hasMessage
is what appears in your unit test output log if the assertion fails.
I found this by noticing the failWithMessage
helper in the custom assert page linked in the question. The JavaDoc for that method points out that it is protected, so it can't be used by callers to set a custom message. It does however mention the as
helper:
Moreover, this method honors any description set with
as(String, Object...)
or overridden error message defined by the user withoverridingErrorMessage(String, Object...)
.
... and the overridingErrorMessage helper, which completely replaces the standard AssertJ expected: ... but was:...
message with the new string provided.
The AssertJ homepage doesn't mention either helper until the features highlights page, which shows examples of the as
helper in the Soft Assertions section, but doesn't directly describe what it does.
Use the inbuilt as()
method in AssertJ. For example:
assertThat(myTest).as("The test microservice is not active").isEqualTo("active");