We have just released the 0.2.0 version of the assertj-vavr library. With this release, you get the assertions for Vavr’s Multimap type, a bunch of new ones for Map, the next two for Either, and assumptions for all supported Vavr types. Let’s got through them in more detail.

Map assertions

While the support of Maps was already there, we’ve been missing methods allowing us to check for containment of specific keys or values. The new version of the library makes it possible:

// given
private static final Tuple2<String, String> FRODO = Tuple.of("frodo", "hobbit");
private static final Tuple2<String, String> GIMLI = Tuple.of("gimli", "dwarf");
private static final Tuple2<String, String> LEGOLAS = Tuple.of("legolas", "elf");
private static final Map<String, String> PERSONS = List.of(FRODO, GIMLI, LEGOLAS).toMap(tup -> tup);
// somewhere in tests
assertThat(PERSONS)
.containsOnly(List.of(FRODO, GIMLI, LEGOLAS))
.containsOnlyKeys(FRODO._1, GIMLI._1, LEGOLAS._1)
.containsKey("frodo")
.containsKeys("frodo", "legolas")
.containsValue("dwarf")
.containsValues("elf", "dwarf")
.doesNotContainKey("aragorn")
.doesNotContainKeys("aragorn", "boromir")
.doesNotContainValue("man")
.doesNotContainValues("man", "orc");

If we are using a map that has a consistent iteration order (like LinkedHashMap or TreeMap), there is new assert allowing to check the order of entries:

// given
private static final Map<String, String> PERSONS_ORDERED = TreeMap.ofEntries(GIMLI, FRODO);
// in test
assertThat(PERSONS_ORDERED).containsExactly(FRODO, GIMLI);

Additionally, we can check whether an entry with given key satisfies provided condition:

assertThat(PERSONS).hasEntrySatisfying("frodo", new Condition<String>() {
@Override
public boolean matches(String value) {
return value.equals("hobbit");
}
});

Multimap assertions

The new release adds support of Multimap types. The range of assertions we can make is the same as for Map:

// given
private static final Tuple2<String, String> FRODO = Tuple.of("hobbit", "frodo");
private static final Tuple2<String, String> SAM = Tuple.of("hobbit", "sam");
private static final Tuple2<String, String> GIMLI = Tuple.of("dwarf", "gimli");
private static final Tuple2<String, String> LEGOLAS = Tuple.of("elf", "legolas");
private static final Multimap<String, String> RACES =
HashMultimap.withSeq().ofEntries(FRODO, SAM, GIMLI);
private static final BiConsumer<String, String> OK_CONSUMER = (key, value) -> Assertions.assertThat(key).isLowerCase();
// somewhere in tests
assertThat(RACES).allSatisfy(OK_CONSUMER)
.containsAnyOf(FRODO, LEGOLAS)
.contains(FRODO)
.containsAllEntriesOf(List.of(FRODO, GIMLI))
.containsEntry("hobbit", "frodo")
.containsExactly(GIMLI, SAM, FRODO)
.containsKey("hobbit")
.containsKeys("hobbit", "dwarf")
.containsOnly(List.of(SAM, FRODO, GIMLI))
.containsOnlyKeys("hobbit", "dwarf")
.containsValue("frodo")
.containsValues("frodo", "gimli")
.doesNotContainEntry("elf", "legolas")
.doesNotContain(LEGOLAS)
.doesNotContainKey("elf")
.doesNotContainKeys("elf", "man")
.doesNotContainValue("legolas")
.doesNotContainValues("legolas", "aragorn")
.hasSameSizeAs(new String[]{"frodo", "gimli", "sam"})
.hasSameSizeAs(Array.of(FRODO, GIMLI, SAM))
.hasSize(3)
.isNotEmpty(); // and isEmpty() / isNullOrEmpty()
assertThat(RACES).hasEntrySatisfying("hobbit", new Condition<String>() {
@Override
public boolean matches(String value) {
return value.equals("sam");
}
});

New Either assertions

EitherAssert gets two new methods checking whether a value on left or right satisfies provided criteria:

Either<Integer, String> actualLeft = Either.left(42);
assertThat(actualLeft).hasLeftValueSatisfying(it -> Assertions.assertThat(it).isEqualTo(42));
Either<Integer, String> actualRight = Either.right("42");
assertThat(actualRight).hasRightValueSatisfying(it -> Assertions.assertThat(it).isEqualTo("42"));

Assumptions

The new release adds assumptions for all supported Vavr types. The starting point is org.assertj.vavr.api.VavrAssumptions class and its assumeThat static methods. The API matches the one for assertions. We can now write conditional tests, as presented below. Failing assumption marks a given test as ignored, not as failed.

// given
Option<String> empty = Option.none();
// this one fails
assumeThat(empty).isDefined();
// so the assertion won't be checked and test is ignored
assertThat(empty).contains("yay!);
// given
Either<String, Integer> value = Either.right(42);
// this oone passes
assumeThat(value).isRight();
// so the assertion is checked
assertThat(value).containsRight(42);

TryAssert update

With this release, we have updated the error message when calling TryAssert.isSuccess() fails. Now, the output is more informative and presents the content of the Try.Failure instance, we’ve been checking.

Contribs

A big thank you go to Alex Dukhno and James Lorenzen for providing PRs and ideas on how to extend the library. And last but not least, special thanks go to Maciek Opala for competent reviews all of my PRs made to the project!

As you may spot, I released the previous version almost nine months ago. That’s a long time. Unfortunately, I had not enough free time to sit down on the project. And it doesn’t look like it is going to change shortly. Thus, if you have any idea on how to extend the project, do not hesitate and make an issue. Or even better – create a pull request. Your contribution is more than welcome!

Image by Hans Braxmeier from Pixabay

Categories: testing

2 Comments

December 18 evening Java digest – BLOG – THE HACKER NEWS · December 23, 2019 at 11:30 am

[…] it assertj-vavr v0.2.0. Library lies on github (95 commits, 30 stars) and provides assists for vavr. Vavr, in turn, is a […]

Java digest for December 18 / Blog of the JUG Ru Group company / geek magazine – Developers · January 19, 2020 at 2:00 am

[…] it assertj-vavr v0.2.0. Library lies on github (95 commits, 30 stars) and provides assists for vavr. Vavr, in turn, is a […]

Leave a Reply to December 18 evening Java digest – BLOG – THE HACKER NEWS Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.