Say I have a class like this:
public class Character { public Character(String name){ this.name = name; } private String name; public String getName() { return name; } }
And later, a Map
Map<Character, Integer> characterAges = new HashMap<Character, Integer>(); characterAges.put(new Character("Frodo"), 34);
Using assertj, what is the best way to test that characterAges includes the “Frodo” character? For the age, I can do:
assertThat(characterAges).hasValue(34);
And I know I could do:
assertThat(characterAges.keySet()) .extracting("name") .contains("Frodo");
But then I lose my fluency. What I really want it something like this:
assertThat(characterAges) .hasKey(key.extracting("name").contains("Frodo") .hasValue(34);
Or even better, so that I can make sure my key and value match:
assertThat(characterAges) .hasEntry(key.extracting("name").contains("Frodo"), 34);
Is something like this possible?
Advertisement
Answer
There is no easy solution for this. One way is to implement a custom Assertion for the character map. Here is a simple custom Assertion example for this problem:
public class CharacterMapAssert extends AbstractMapAssert<MapAssert<Character, Integer>, Map<Character, Integer>, Character, Integer> { public CharacterMapAssert(Map<Character, Integer> actual) { super(actual, CharacterMapAssert.class); } public static CharacterMapAssert assertThat(Map<Character, Integer> actual) { return new CharacterMapAssert(actual); } public CharacterMapAssert hasNameWithAge(String name, int age) { isNotNull(); for (Map.Entry<Character, Integer> entrySet : actual.entrySet()) { if (entrySet.getKey().getName().contains(name) && (int) entrySet.getValue() == age) { return this; } } String msg = String.format("entry with name %s and age %s does not exist", name, age); throw new AssertionError(msg); } }
In the test case:
assertThat(characterAges).hasNameWithAge("Frodo", 34);
Be aware that you have for every custom data structure to write your own assertion. For you Character
class you can generate a assertion with the AssertJ assertions generator.
Update Java 8
With Java 8 can also the Lambda Expression used
assertThat(characterAges).matches( (Map<Character, Integer> t) -> t.entrySet().stream().anyMatch((Map.Entry<Character, Integer> t1) -> "Frodo".equals(t1.getKey().getName()) && 34 == t1.getValue()), "is Frodo and 34 years old" );