In this recipe, we will create a custom AssertJ assertion. Please refer to the previous recipe for the presented assertions in the test because in the current recipe, we will combine them into our custom assertions:
For this recipe, our system under test will be a NewPersonGenerator
class that will call an external service, NewIdentityCreator
, to generate a new identity for the current person, as shown in the following code:
public class NewPersonGenerator { private final NewIdentityCreator newIdentityCreator; public NewPersonGenerator(NewIdentityCreator newIdentityCreator) { this.newIdentityCreator = newIdentityCreator; } public Person generateNewIdentity(Person person) { String newName = newIdentityCreator.createNewName(person); int newAge = newIdentityCreator.createNewAge(person); List<Person> newSiblings = newIdentityCreator.createNewSiblings(person); return new Person(newName, newAge, newSiblings); } }
To create and use a custom AssertJ assertion in your tests, you have to perform the following steps:
AbstractAssert
class, which takes two bounds of generics: one is the assertion's class and the other is the asserted object's class.Assertions
class (in order to access core assertions). You will put your custom assertion factory method here.assertThat(T object)
/then(T object)
static factory method that will instantiate your custom assertion.AssertJ
assertion in the assertion phase of your test.The following snippet depicts the aforementioned scenario for JUnit (refer to Chapter 1, Getting Started with Mockito, for information on the TestNG configuration):
@RunWith(MockitoJUnitRunner.class) public class NewPersonGeneratorTest { @Mock NewIdentityCreator newIdentityCreator; @InjectMocks NewPersonGenerator systemUnderTest; @Test public void should_return_person_with_new_identity() { // given Person person = new Person("Robert", 25, asList(new Person("John"), new Person("Maria"))); given(newIdentityCreator.createNewName(person)).willReturn("Andrew"); given(newIdentityCreator.createNewAge(person)).willReturn(45); given(newIdentityCreator.createNewSiblings(person)).willReturn(asList(new Person("Amy"), new Person("Alejandro Gonzales"))); // when Person newPerson = systemUnderTest.generateNewIdentity(person); // then then(newPerson).isNotEqualTo(person) .hasNameEqualTo("Andrew") .hasAgeGreaterThan(25) .containsSiblings(new Person("Amy"), new Person("Alejandro Gonzales")); } }
The class shown in the following code contains all of the assertThat
methods from the Assertions
class and a then(…)
method that instantiates our custom PersonAssert
assertion:
public class MyBddAssertions extends BDDAssertions { public static PersonAssert then(Person actual) { return new PersonAssert(actual); } }
The implementation of the custom assertion is shown as follows:
public class PersonAssert extends AbstractAssert<PersonAssert, Person> { protected PersonAssert(Person actual) { super(actual, PersonAssert.class); } public PersonAssert hasNameEqualTo(String name) { String actualName = actual.getName(); assertThat(actualName).isEqualTo(name); return this; } public PersonAssert hasAgeGreaterThan(int age) { int actualAge = actual.getAge(); assertThat(actualAge).isGreaterThan(age); return this; } public PersonAssert containsSiblings(Person... siblings) { List<Person> actualSiblings = actual.getSiblings(); assertThat(actualSiblings).contains(siblings); return this; } }
The flow regarding the creation of a custom AssertJ assertion is rooted deeply in the core of AssertJ that is described in greater depth in the previous recipe, so please refer to it for more information on how it exactly works.
It's beneficial to have a custom class grouping your assertThat(…)
/then(…)
methods that extend the Assertions
class. You will have a single static import statement and will access all of the Assertions
static methods.
AssertJ allows you to easily create assertions for your classes. It comes with a command-line tool and a Maven plugin. You have to pass the fully-qualified names of classes or the entire packages of classes for which you want to create assertions. Once the generator finishes its job, you will have the assertion classes generated with all of the assertion methods for each of the fields present.
For more information on this feature, please refer to the documentation at http://joel-costigliola.github.io/assertj/assertj-assertions-generator.html
3.136.17.12