Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Assertions

An assertion is a method that checks a condition and stops the test with an error if the condition is false. All JUnit assertions are static methods of the org.junit.jupiter.api.Assertions class. Besides assertEquals there are a dozen more; this lesson covers the ones you need every day.

The blog post

From here on, some examples test the blog. A post is a record in src/main/java/com/example/blog/Post.java:

// src/main/java/com/example/blog/Post.java
package com.example.blog;
 
public record Post(Long id, String title, String author, boolean published) {
 
    public Post publish() {
        return new Post(id, title, author, true);
    }
}

A new post has no id yet and is a draft. publish() does not change the record, it returns a published copy.

Main assertions

AssertionPasses when
assertEquals(expected, actual)The values are equal by equals()
assertNotEquals(a, b)The values differ
assertTrue(condition) / assertFalse(condition)The condition is true / false
assertNull(value) / assertNotNull(value)The value is null / not null
assertSame(a, b)It is the same object, a == b
assertIterableEquals(expected, actual)Two collections have equal elements in the same order
fail("message")Never: fails the test unconditionally
// src/test/java/com/example/blog/PostTest.java
package com.example.blog;
 
import org.junit.jupiter.api.Test;
 
import static org.junit.jupiter.api.Assertions.*;
 
class PostTest {
 
    @Test
    void newPostIsDraft() {
        Post post = new Post(null, "Hello, JUnit", "anna", false);
 
        assertNull(post.id());
        assertFalse(post.published());
    }
 
    @Test
    void publishReturnsPublishedCopy() {
        Post draft = new Post(1L, "Hello, JUnit", "anna", false);
 
        Post published = draft.publish();
 
        assertNotNull(published);
        assertTrue(published.published(), "publish() must set the flag");
        assertFalse(draft.published(), "the original post must not change");
    }
}

The import with * brings in all assertions at once. Both tests pass.

A message for the failure

The last parameter of any assertion is a message. Without it, assertTrue only says expected: <true> but was: <false>; with it, the reason is clear:

org.opentest4j.AssertionFailedError: publish() must set the flag ==> expected: <true> but was: <false>

If building the message is expensive, pass a lambda: () -> "post " + post — it is called only when the check fails.

Several checks at once: assertAll

Normally the test stops at the first failed assertion, and you do not know about the others. assertAll runs every check and reports all failures together:

// src/test/java/com/example/blog/PostTest.java
@Test
void publishKeepsOtherFields() {
    Post published = new Post(1L, "Hello, JUnit", "anna", false).publish();
 
    assertAll(
            () -> assertEquals(1L, published.id()),
            () -> assertEquals("Hello, JUnit", published.title()),
            () -> assertEquals("anna", published.author()),
            () -> assertTrue(published.published())
    );
}

If the test expected the title "Hello" and the author "oleg", the report lists both failures:

org.opentest4j.MultipleFailuresError:
Multiple Failures (2 failures)
	org.opentest4j.AssertionFailedError: expected: <Hello> but was: <Hello, JUnit>
	org.opentest4j.AssertionFailedError: expected: <oleg> but was: <anna>

Collections

assertIterableEquals compares element by element and tells you where the difference is:

// src/test/java/com/example/blog/PostTest.java
assertIterableEquals(List.of("First", "Second"), List.of("First", "Third"));
org.opentest4j.AssertionFailedError: iterable contents differ at index [1], expected: <Second> but was: <Third>

Common mistake

BigDecimal.equals() compares not only the value but also the scale — the number of digits after the point. 36 and 36.00 are different for it:

// src/test/java/com/example/shop/PriceCalculatorTest.java
assertEquals(new BigDecimal("36"), calculator.total(new BigDecimal("12"), 3));
org.opentest4j.AssertionFailedError: expected: <36> but was: <36.00>

Write the expected amount with the same scale as the code returns ("36.00"), or compare with compareTo: assertEquals(0, expected.compareTo(actual)). AssertJ has a ready-made isEqualByComparingTo for this.

Thanks for reading!

Donate to the site — we work hard for you.