I've used assertj in a lot of projects, I prefer it by a wide margin over
using only junit.

On Tue, Mar 10, 2020 at 9:45 AM David Capwell <dcapw...@gmail.com> wrote:

> +1 from me
>
> In CASSANDRA-15564 I build my own assert chain to make the tests cleaner;
> did it since assertj wasn't there.
>
> On Tue, Mar 10, 2020, 9:28 AM Kevin Gallardo <kevin.galla...@datastax.com>
> wrote:
>
> > I would like to propose adding AssertJ <https://assertj.github.io/doc/>
> as
> > a test dependency and therefore have it available for writing
> > unit/distributed/any test assertions.
> >
> > In addition to the examples mentioned on the AssertJ docs page (allows to
> > do elaborate and comprehensible assertions on Collections, String, and
> > *custom
> > assertions*), here's an example of a dtest I was looking at, that could
> be
> > translated to AssertJ syntax, just to give an idea of how the syntax
> would
> > apply:
> >
> > *JUnit asserts*:
> > try {
> >    [...]
> > } catch (Exception e) {
> >     Assert.assertTrue(e instanceof RuntimeException);
> >     RuntimeException re = ((RuntimeException) e);
> >     Assert.assertTrue(re.getCause() instanceof ReadTimeoutException);
> >     ReadTimeoutException rte = ((ReadTimeoutException) e.getCause());
> >     Assert.assertTrue(rte.getMessage().contains("blabla")
> >                       && rte.getMessage().contains("andblablo"));
> > }
> >
> > *AssertJ style:*
> > try {
> >     [...]
> > } catch (Exception e) {
> >     Assertions.assertThat(e)
> >             .isInstanceOf(RuntimeException.class)
> >             .hasCauseExactlyInstanceOf(ReadTimeoutException.class)
> >             .hasMessageContaining("blabla")
> >             .hasMessageContaining("andblablo");
> > }
> >
> > The syntax is more explicit and more comprehensible, but more
> importantly,
> > when one of the JUnit assertTrue() fails, you don't know *why*, you only
> > know that the resulting boolean expression is false.
> > If a failure happened with the assertJ tests, the failure would say
> > "Exception
> > did not contain expected message, expected "blabla", actual "notblabla""
> > (same for a lot of other situations), this makes debugging a failure,
> after
> > a test ran and failed much easier. With JUnit asserts you would have to
> > additionally add a message explaining what the expected value is *and*
> > what the
> > actual value is, for each assert that is more complex than a assertEquals
> > on a number, I suppose. I have seen a lot of tests so far that only test
> > the expected behavior via assertTrue and does not show the incorrect
> values
> > when the test fails, which would come for free with AssertJ.
> >
> > Other examples randomly picked from the test suite:
> >
> >
> >
> *org.apache.cassandra.repair.RepairJobTest#testNoTreeRetainedAfterDistance:*
> > Replace assertion:
> > assertTrue(messages.stream().allMatch(m -> m.verb() == Verb.SYNC_REQ));
> > With:
> > assertThat(messages)
> >     .extracting(Message::verb)
> >     .containsOnly(Verb.SYNC_REQ);
> >
> > As a result, if any of the messages is not a Verb.SYNC_REQ, the test
> > failure will show the actual "Verb"s of messages.
> >
> > Replace:
> > assertTrue(millisUntilFreed < TEST_TIMEOUT_S * 1000);
> > With:
> > assertThat(millisUntilFreed)
> >     .isLessThan(TEST_TIMEOUT_S * 1000);
> >
> > Same effect if the condition is not satisfied, more explicit error
> message
> > explaining why the test failed.
> >
> > AssertJ also allows Custom assertions which are also very useful and
> could
> > potentially be leveraged in the future.
> >
> > This would only touch on the tests' assertions, the rest of the test
> setup
> > and execution remains untouched (still uses JUnit for the test
> execution).
> >
> > Thanks.
> >
> > --
> > Kévin Gallardo.
> >
>

Reply via email to