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.
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.