If you are working with Java, you probably know Vavr library, I guess. It is a great library, and it is my default in every Java project I am working on, as it was with Guava for some time.

Regarding testing, I can say the same thing about AssertJ project. I can hardly imagine writing JUnit tests without fluent assertions in my toolbox.

However, writing assertions with AssertJ for Vavr’s types was somehow challenging. The code did not look as sleek as it should. It was not as readable as it always is when using fluent assertions. The connection between both libraries was a missing piece in such setup.

And finally, the gap is filled!

Some time ago, Grzegorz Piwowarek seeded the project aimed at delivering assertions for Vavr’s types. I joined and after a couple of months, we can provide its initial version.

Before we look at the code, I would thank Joel Costigliola for hosting the project in the assertj domain on GH and two others contributors – Bartek Kuczyński and Alex Dukhno – for their additions.

What’s inside

The first release of assertj-vavr supports 3 types, the most fundamental ones, I believe. These are:
io.vavr.Option,
io.vavr.Try,
– and io.vavr.Either.

You can spot improvement not only in code readability. For failed assertion, you get a more meaningful error message.

Option

With plain AssertJ on board writing assertions for Option type looks like the following:

assertThat(actualOpt.isDefined()).isTrue();
assertThat(actualOpt.get()).isEqualTo(expectedValue);

That is not as fluent as it could be. With assertj-vavr the code is more readable:

assertThat(actualOpt).isDefined();
assertThat(actualOpt).contains(expectedValue);

Try

The same applies to Try instances. Here is an example of using plain AssertJ:

// for Try.Success
assertThat(actualTry.isSuccess()).isTrue();
assertThat(actualTry.get()).isEqualTo(expectedValue);

// for Try.Failure
assertThat(actualTry.isFailure()).isTrue();
assertThat(actualTry.getCause().getMessage).isEqualTo(expectedErrorMessage);
assertThat(actualTry.getCause().getClass()).isEqualTo(NullPointerExcpetion.class);

And with assertj-vavr:

// Try.Success
assertThat(actualTry).contains(expectedValue);

// Try.Failure
assertThat(actualTry).failReasonHasMessage(expectedErrorMessage);
assertThat(actualTry).failBecauseOf(NullPointerExcpetion.class);

Either

As you can guess, in the case of Either examples improvements in readability are as significant as in the above examples.

Using plain Assertj:

// Either.Right
assertThat(actualEither.isRight()).isTrue();
assertThat(actualEither.get()).isEqualTo(expectedRightValue);

// Either.Left
assertThat(actualEither.isLeft()).isTrue();
assertThat(actualEither.getLeft()).isEqualTo(expectedLeftValue);

After migrating to assertj-vavr:

// Either.Right
assertThat(actualEither).isRight();
assertThat(actualEither).containsOnRight(expectedRightValue);

// Either.Left
assertThat(actualEither).isLeft();
assertThat(actualEither).containsOnLeft(expectedLeftValue);

What’s next?

At first, we need your feedback. So, add the library to your Java projects and use it! You can leave your opinion here, in comments, or email me (contact page link). If you have some specific things in mind – create an issue on GitHub.

I think the next step would be the support of Vavr’s collections (maybe Seq and List at first?). However, we have to keep an eye on a revolution that author of Vavr is preparing for us in Vavr v1.0.

 
Photo by Jeff King on Unsplash

Categories: testing

2 Comments

Marek · July 23, 2018 at 10:31 am

Nice and really useful library – i ll for sure use it

i have some ideas about assertion:
In my opinion the
assertThat(actualTry).isSuccess() looks clener then
assertThat(actualTry.isSuccess()).isTrue()

the same with assertThat(actualEither.isRight()).isTrue();
the assertThat(actualEither).isRight() is cleaner and shorter

WDYF?

    Michał · July 23, 2018 at 9:57 pm

    Yes, definitely worth to add. And your proposition is consistent with OptionAssert.isDefined/isEmpty. I’ll add issues for this.

Leave a Reply

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