How do I use Hamcrest with JUnit 5 when JUnit 5 doesn't have an assertThat() function?
Asked Answered
B

2

75

To use Hamcrest with JUnit 4 we use an assertThat() function. However, JUnit 5 is no longer going to have an assertThat() function. How do I use Hamcrest without an assertThat()?

Bifocal answered 7/4, 2017 at 14:9 Comment(0)
B
79

You have to make sure Hamcrest is included in the classpath and then use the assertThat() function provided by Hamcrest. From the current JUnit 5 User Guide - Writing Tests Assertions,

JUnit Jupiter’s org.junit.jupiter.Assertions class does not provide an assertThat() method like the one found in JUnit 4’s org.junit.Assert class which accepts a Hamcrest Matcher. Instead, developers are encouraged to use the built-in support for matchers provided by third-party assertion libraries.

The following example demonstrates how to use the assertThat() support from Hamcrest in a JUnit Jupiter test. As long as the Hamcrest library has been added to the classpath, you can statically import methods such as assertThat(), is(), and equalTo() and then use them in tests like in the assertWithHamcrestMatcher() method below.

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.Test;

class HamcrestAssertionDemo {

    @Test
    void assertWithHamcrestMatcher() {
        assertThat(2 + 1, is(equalTo(3)));
    }

}

Naturally, legacy tests based on the JUnit 4 programming model can continue using org.junit.Assert#assertThat."

Bifocal answered 7/4, 2017 at 14:9 Comment(6)
What blows my mind is, assertThat was supposed to be the new way to do all assertions, and then suddenly JUnit 5 comes out, and somehow still has all the legacy assert methods, but has also removed the only modern one. They were already committed to breaking the API, so you'd think they could have really gone there and removed all the redundant assertion methods. Initially I thought that maybe it was for convenience of migration, but no, the parameter order isn't even the same.Nedanedda
The choice the JUnit 5 team was facing is to either implement a full blown „modern“ assertion lib or to only provide the bare minimum and leave smart assertions to external libraries. The team went with the latter. What Junit4 did was to draw in an external dependency. on a specific version of Hamcrest which was later considered to be a mistake since it lead to many probs with conflicting versions. Having no external deps AT ALL has therefore been a fundamental rule for the JUnit 5 core.Ineffable
@Ineffable OK... but what about assumeThat? It isn't in JUnit 5's Assumptions static methods, and isn't in Hamcrest either. Are we expected to pull in yet another library to get assumptions? Overall it just seems like JUnit 5 half-assed the entire thing. Including no assertions at all would have been better than what they gave us.Nedanedda
To add even more laughs to this whole mess, JUnit 4 has now deprecated assertThat. i.e., the only modern assertion method is now deprecated, while using the legacy ones is not. LOL!Nedanedda
@Trejkaz Tastes and design judgements obviously differ.Ineffable
Add a dependency to the Hamcrest library and then use MatcherAssert.assertThat, it's a 1:1 replacement for JUnit 4 one. See hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/…Muttra
K
11

See https://github.com/junit-team/junit5/issues/147:

you can use both, Hamcrest and AssertJ, in JUnit5. Both frameworks have a simple assertThat method, that you can import and use if wanted.

Currently, we do not plan to support these frameworks within our own Assertions to avoid the dependencies. Still, one can use them very well.

Kenwood answered 18/7, 2018 at 13:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.