Skip to content

Tips and tricks

joel-costigliola edited this page May 6, 2012 · 45 revisions

(to main page)

Here's some tips we are using to make writing tests easier and more elegant.
Please share your tips with us, this page can be edited by everybody !

Tips

Assertions on extracted properties of a collection/array

When you are persisting objects, your persistent objects usually have persistent ids. You are writing a DAO/repository tests querying the datastore and you only want to check that the returned objects have the expected ids.

Without you would write something like

List<TolkienCharacter> fellowshipOfTheRing = tolkienDao.findHeroes();

// extract the ids ...
List<Long> ids = new ArrayList<Long>();
for (TolkienCharacter tolkienCharacter : fellowshipOfTheRing) {
  ids.add(tolkienCharacter.hashCode());
}
// ... and finally assert something
assertThat(ids).contains(1L, 2L, 3L);

It is killing to have to extract ids, so we have made this scenario much easier to write, we take for you to extract the properties, look below :

List<TolkienCharacter> fellowshipOfTheRing = tolkienDao.findHeroes();
// no more manual ids extraction 
assertThat(extractProperty("id").from(fellowshipOfTheRing)).contains(1L, 2L, 3L);

You can even extract nested properties using the dot notation, for example :

assertThat(extractProperty("race.name").from(fellowshipOfTheRing)).contains("Hobbit", "Elf")

See more examples in test collection_assertions_on_extracted_property_values_example from fest-examples project.

Using a custom comparison strategy in assertions

TO BE COMPLETED ...

Filtering a group of objects before making assertions

// with(property).equalsTo(someValue) works by instrospection on specified property
assertThat(filter(fellowshipOfTheRing).with("race").equalsTo(HOBBIT).get()).containsOnly(sam, frodo, pippin, merry);
// same thing - shorter way
assertThat(filter(fellowshipOfTheRing).with("race", HOBBIT).get()).containsOnly(sam, frodo, pippin, merry);

// nested property are supported
assertThat(filter(fellowshipOfTheRing).with("race.name").equalsTo("Man").get()).containsOnly(aragorn, boromir);

// you can apply different comparison
assertThat(filter(fellowshipOfTheRing).with("race").notIn(HOBBIT, MAN).get()).containsOnly(gandalf, gimli, legolas);
assertThat(filter(fellowshipOfTheRing).with("race").in(MAIA, MAN).get()).containsOnly(gandalf, boromir, aragorn);
assertThat(filter(fellowshipOfTheRing).with("race").notEqualsTo(HOBBIT).get()).contains(gandalf, boromir, aragorn, gimli,
                                                                                        legolas);
// you can chain multiple filter criteria 
assertThat(filter(fellowshipOfTheRing).with("race").equalsTo(MAN).and("name").notEqualsTo("Boromir").get()).contains(aragorn);
}

Filtering with Condition comes with two methods : being(Condition) and having(Condition), they do the same verification, just pick the one that makes your code the more readable !

// having(condition) example
Condition<Player> mvpStats= new Condition<Player>() {
  @Override
  public boolean matches(Player player) {
    return player.getPointsPerGame() > 20 && (player.getAssistsPerGame() >= 8 || player.getReboundsPerGame() >= 8);
  }
};
assertThat(filter(players).having(mvpStats).get()).containsOnly(rose, james);

// being(condition) example : same condition can be applied but is renamed to be more readable
Condition<Player> potentialMvp= mvpStats;
assertThat(filter(players).being(potentialMvp).get()).containsOnly(rose, james);