BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Testing

Testing

JUnit 4 and Hamcrest

JUnit 4 is the older test framework still found in many projects: @Before/@After, @RunWith, @Rule, @Test(expected = ...) and org.junit.Assert.

๐Ÿ”Ž Unravel this example

At a glance

Mental model

The older edition of the textbook: same lessons as the new one, with different chapter names, and still in use in many classrooms.

What happens, in order
  1. 1Mapping to JUnit 5: @Before is @BeforeEach, @After is @AfterEach, @BeforeClass is @BeforeAll, @Ignore is @Disabled, @RunWith(X.class) and @Rule become @ExtendWith
  2. 2@Test(expected = IllegalArgumentException.class) checks an exception (JUnit 5: assertThrows)@Test(timeout = 1000) fails slow tests.
  3. 3Assert.assertEquals(expected, actual) puts the expected value firstHamcrest: assertThat(list, hasItem("a")), is(...), containsString(...).
  4. 4@RunWith(MockitoJUnitRunner.class) initialises @Mock fields; @Parameterized.Parameters runs a test over a table
Remember
Watch out
Importing the wrong @Test annotationSwapping expected and actual in assertEqualsMixing runner styles
Example (highlighted lines explain it)
import org.junit.*;import static org.junit.Assert.*;public class StackTest {  private java.util.ArrayDeque<Integer> stack;  @Before public void setUp() { stack = new java.util.ArrayDeque<>(); }  @After public void tearDown() { stack.clear(); }  @Test public void pushAndPop() { stack.push(1); assertEquals(Integer.valueOf(1), stack.pop()); }  @Test(expected = java.util.NoSuchElementException.class) public void emptyPop() { stack.pop(); }  @Ignore("not ready") @Test public void later() {}}
  1. line 2 uses Assert, the core of JUnit 4 and Hamcrest
  2. line 5 uses Before, the core of JUnit 4 and Hamcrest
  3. line 6 uses After, the core of JUnit 4 and Hamcrest
  4. line 9 uses Ignore, the core of JUnit 4 and Hamcrest
Read the full explanation (about 1 min)

JUnit 4 is the older test framework still found in many projects: @Before/@After, @RunWith, @Rule, @Test(expected = ...) and org.junit.Assert. Hamcrest matchers (assertThat(x, is(5))) express expectations.

A mental model

The older edition of the textbook: same lessons as the new one, with different chapter names, and still in use in many classrooms.

How it works

Mapping to JUnit 5: @Before is @BeforeEach, @After is @AfterEach, @BeforeClass is @BeforeAll, @Ignore is @Disabled, @RunWith(X.class) and @Rule become @ExtendWith.

@Test(expected = IllegalArgumentException.class) checks an exception (JUnit 5: assertThrows). @Test(timeout = 1000) fails slow tests.

Assert.assertEquals(expected, actual) puts the expected value first. Hamcrest: assertThat(list, hasItem("a")), is(...), containsString(...).

@RunWith(MockitoJUnitRunner.class) initialises @Mock fields; @Parameterized.Parameters runs a test over a table.

Going deeper

JUnit 4 and 5 can run together through the Vintage engine, so a project can migrate step by step. Do not mix the annotations of the two in one class: org.junit.Test and org.junit.jupiter.api.Test look the same and only one of them runs.

A very common reason for a test that "does not run" is the wrong import for @Test in a Spring Boot project that now defaults to JUnit 5.

@Rule classes such as TemporaryFolder and ExpectedException are replaced by @TempDir and assertThrows.

Under the hood

JUnit 4 uses a Runner that finds @Test methods by reflection and runs them with @Rule interceptors; JUnit 5 splits this into the Platform (launching) and engines.

Common mistakes

  • Importing the wrong @Test annotation.
  • Swapping expected and actual in assertEquals.
  • Mixing runner styles.

How Unravel recognises it

When you paste code, Unravel looks for these signs of junit 4 and hamcrest. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is JUnit 4 and Hamcrest?

JUnit 4 is the older test framework still found in many projects: @Before/@After, @RunWith, @Rule, @Test(expected = ...) and org.junit.Assert. Hamcrest matchers (assertThat(x, is(5))) express expectations.

What are the most common mistakes with JUnit 4 and Hamcrest?

Importing the wrong @Test annotation. Swapping expected and actual in assertEquals. Mixing runner styles.

How can I see JUnit 4 and Hamcrest in real code?

Paste your own Java into Unravel and it will point out where junit 4 and hamcrest appears, explain how it works at the detail level you choose, and draw the flow of the code around it.