Creating custom AssertJ assertions

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:

Getting ready

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);
    }
}

How to do it...

To create and use a custom AssertJ assertion in your tests, you have to perform the following steps:

  1. Attach your AssertJ dependencies.
  2. Create a class that extends the AbstractAssert class, which takes two bounds of generics: one is the assertion's class and the other is the asserted object's class.
  3. Implement a constructor that has two parameters: one that passes the actual object and the other that passes the assertion's class.
  4. Define custom methods that perform assertions and return the assert itself (in order to construct a fluent iterable interface).
  5. Create a class that extends the Assertions class (in order to access core assertions). You will put your custom assertion factory method here.
  6. Create an assertThat(T object)/then(T object) static factory method that will instantiate your custom assertion.
  7. Call your custom 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;
  }

}

How it works...

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.

There's more...

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

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.17.12