linkedin Skip to Main Content
Just announced: We now support interviewing in spreadsheets!
Back to blog

How To Use Assert In JUnit With Examples

Development

Assertions are at the heart of unit testing. They’re crucial in giving unit tests their “self-validating” characteristic, without which they’d be practically useless. In this post, you’ll learn more about the Assert JUnit class and how you can use it to write your assertions when unit testing your Java code.

This will be a practical post, but we’ll start with a brief theoretical digression to explain what “assert” means in JUnit. Then, it’s time to roll up your sleeves. You’ll learn the following:

  • The process for installing JUnit 5
  • How to create a sample project for testing
  • What the main assertion methods are and how they work

Let’s get started.

What is Assert in JUnit?

In JUnit, Assert is a class that contains many assertion methods you can use when writing unit tests. To understand what that means, you must take a step back and learn about the structure of unit tests first.

Though this is far from being a rule, a unit test typically contains three phases:

  • First, you prepare the values for your test.
  • Then, you execute the action you want to test.
  • Finally, you compare the results you got to what you expected to get.

Unit test frameworks enable you to perform said comparisons by using assertions. An assertion is a type of special syntax you can use to express an expectation in your test code. If the expectation proves true, your test passes; otherwise, it fails. That’s why the structure above is known as the arrange-act-assert pattern.

So, the JUnit Assert class is what allows you to write assertions in your JUnit tests. There are many assertions available; the main ones enable you to verify the following:

  • The equality of two values
  • Whether an object is null
  • The logical value of a boolean variable
  • Whether two variables point to the same object in memory

Let’s see how to use assertions in practice.

Installing JUnit 5 and creating a sample project

Start by creating a new Java project and open it with the IDE or text editor you’re most comfortable with. The next step is to install JUnit 5 on your project. JUnit 5 is the latest major version of the framework, and it’s a complete rewrite. Rather than being a simple component, JUnit 5 is made up of several independent components. To be able to write tests, you need at least JUnit Platform and JUnit Jupiter. Since I’m using Maven, I’ll add the following to my pom.xml file:

<dependency>

<groupId>org.junit.jupiter</groupId>

<artifactId>junit-jupiter-engine</artifactId>

<version>5.2.0</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.junit.platform</groupId>

<artifactId>junit-platform-runner</artifactId>

<version>1.2.0</version>

<scope>test</scope>

</dependency>Code language: HTML, XML (xml)

Now, go under src/test/java and create a new Java class. Call it DemoTest and paste the following code on it:

import org.junit.Test;

import static org.junit.Assert.*;

public class DemoTest {

}Code language: Java (java)

The main JUnit Assert methods

With your demo project in place, it’s time to start writing some assertions.

assertEquals()

assertEquals() is probably the most used assertion. With it, you can compare two values and see whether they’re equal. Here’s an example of assertEquals() that uses two overloads of the method, one for integers and the other for strings:

@Test
    public void assertEquals_demo() {
        // integers
        int expected = 4;
        int actual = 2 + 2;
        assertEquals(expected, actual);


        // strings
        assertEquals("JUnit5", "JUnit" + "5");
    }
Code language: Java (java)

Generally speaking, you should avoid more than one assertion per test method, but this is just an example here. 

Also, remember that argument order matters when using assertEquals(). The first argument represents the result you expect to get after the “act” phase of your test, and the second one is what you actually got. Those values are then used in the error message when the test fails, so mixing them up can throw off your test results

Let’s see a test failure example. I’ll go back to the previous example, and in the line where I assign the expected variable, I’ll pass 5 to it instead of 4. When I run the test, I get this result:

java.lang.AssertionErrorExpected: 5

Actual: 4Code language: CSS (css)

A warning on reference types

Before moving on, there’s something you need to be aware of when dealing with reference types. For that, consider a simple class:

public class Person {

    private final String name;

    private final int age;

    public Person(String name, int age) {

        this.name = name;

        this.age = age;

    }

}Code language: Java (java)

Now, consider the following test:

p1 = new Person("John Doe", 32);

var p2 = new Person("John Doe", 32);

assertEquals(p1, p2);Code language: Java (java)

You might think that such a test would pass, but it fails:

java.lang.AssertionErrorExpected :Person@17d99928

Actual   :Person@3834d63f

<Click to see difference>Code language: CSS (css)

That’s because classes are reference types. As such, when you use assertEquals, only the references of the objects are compared by default. Even though p1 and p2 have the same values, they refer to different objects in the heap memory, so they’re considered different.

However, we really want to compare those two objects by their values, not their references. In other words, we want structural equality rather than referential equality. Achieving that is easy: you’d have to override the equals() method on the Person class.

@Override

public boolean equals(Object obj) {

if (obj == this)

return true;

if (!(obj instanceof Person)) {

return false;

}

Person other = (Person) obj;

return other.name.equals(this.name) && other.age == this.age;

}Code language: Java (java)

A useful overload

There are multiple versions (overloads) of the assertEquals() method that can be used with different data types such as long, String, double, float, int, etc. Each of these versions also has a variant that includes an additional String parameter called message. This variant can be used to specify a message to be displayed if the test fails. This can be useful when multiple tests fail simultaneously, as it allows for faster identification of the issue.

By the way, all assertion methods have an overload like that. So it’d be redundant to provide an example for each. You’ll see an example of the message parameter being used soon.

assertNotEquals()

It’s common for assertion methods to have an inverse method. assertNotEquals() asserts that two objects are different. Like its counterpart, you should pay attention to the order of the parameters: 

  • First comes the unexpected value
  • Then the actual value

assertTrue()

The assertTrue() method asserts that a given boolean value is true. As an example, let’s rewrite the previous assertion, replacing assertEquals with assertTrue:

assertTrue(p1.equals(p2));Code language: Java (java)

This is just an example. In real test code, it’s better to use assertEquals over assertTrue when comparing two values. That’s because assertEquals will give you a more useful error message when a failure occurs, following the pattern “expected: x; actual: y.”

Use assertTrue(), for instance, to assert the return value of a method of type boolean. Here’s an example:

@Test
public void assertTrue_demo() {
	int yearsOfEmployment = 5;
	String name = "John Doe";
	Employee emp = new Employee(name, yearsOfEmployment);
	assertTrue(emp.isEligibleForSabbatical());
}Code language: Java (java)

This is the code for the Employee class:

public class Employee {

    private final String name;

    private final int yearsOfEmployment;

    public Employee(String name, int yearsOfEmployment) {

        this.name = name;

        this.yearsOfEmployment = yearsOfEmployment;

    }

    public boolean isEligibleForSabbatical() {

        return yearsOfEmployment >= 5;

    }

}Code language: Java (java)

assertTrue() has a useful overload in which you can provide a message when the test fails:

@Test
public void assertTrue_demo() {
	int yearsOfEmployment = 5;
	String name = "John Doe";
	Employee emp = new Employee(name, yearsOfEmployment);
	assertTrue(
			"Employees with 5 or more years of employment are eligible for a sabbatical",
			emp.isEligibleForSabbatical());
}Code language: Java (java)

I’ll go into the production method and add a bug:

return yearsOfEmployment >= 6;Code language: Java (java)

Now the test fails with a helpful message:

java.lang.AssertionError: Employees with 5 or more years of employment are eligible for a sabbatical

at org.junit.Assert.fail(Assert.java:89)

at org.junit.Assert.assertTrue(Assert.java:42)

at DemoTest.assertTrue_demo(DemoTest.java:10)

[...]Code language: CSS (css)

assertFalse()

As its name suggests, the assertFalse() method is the opposite of assertTrue() – the test passes when its parameter evaluates to false. 

assertSame()

When discussing assertEquals(), you’ve learned that reference types (objects) are compared regarding their references. That’s why assertEquals() fails for objects that don’t override the equals() method. What if you really wanted to verify reference equality? In this case, you’d use the assertSame() method:

var p1 = new Person("Jane Doe", 20);

var p2 = p1;

assertSame(p1, p2);Code language: Java (java)

assertNotSame()

If you wanted to assert that two variables don’t point to the same object, you’d use the opposite method: assertNotSame()

assertNull()

You use the assertNull() method to verify whether the specified parameter contains a null reference:

PhoneNumber candidate = PhoneNumber.tryParse("this isn't a phone number");
assertNull(candidate);Code language: Java (java)

assertNotNull()

You should know the drill by now: this is the inverse of the previous one, and I won’t bore you with an example. 

Just a personal anecdote: I rarely use assertNotNull() when writing my tests. Most of the time, I find that there are more useful assertions I can write. For instance, I often have a specific value I want to compare the result of the operation to, in which case assertEquals() is the answer.

assertThrows()

When writing tests, not only must you test the scenario in which everything works fine—i.e. the happy path—but you should also test the sad path scenarios.

Languages like Java use the concept of exceptions to express unintended behaviors and errors in methods. So you’ll often have to write tests that verify whether a given exception happens.

Let’s go back to the Person class from previous examples and change its constructor, adding two guard clauses:

public Person(String name, int age) {
	if (name == null || name.trim().isEmpty())
		throw new IllegalArgumentException("Name shouldn't be empty!");


	if (age < 0)
		throw new IllegalArgumentException("Age can't be negative!");


	this.name = name;
	this.age = age;
}Code language: Java (java)

You’ll agree with me that it’s reasonable to prohibit empty names and negative ages. But now it’d be great to have tests for these scenarios for two reasons:

  • Documentation: The tests will serve as a specification of the class’s behavior.
  • Code quality: The tests will prevent the guard clauses from being removed or changed.

Let’s write a test for the negative age scenario:

@Test
public void negativeAgesNotAllowed() {
	int age = -1;
	String name = "John Doe";
	assertThrows(IllegalArgumentException.class, () -> new Person(name, age));
}Code language: Java (java)

As you can see, using assertThrows isn’t hard: you pass the expected exception class as the first argument and a lambda expression representing the action to be executed as the second one. 

As an exercise, try implementing tests for these scenarios for the name argument:

  • An empty string
  • A string with spaces
  • null

How about you try out JUnit in the sandbox below?

Assert your way to better software

In this post, you’ve learned what assertions are, why they’re crucial for unit testing, and how to write assertions using the JUnit Assert class.

Where should you go next? My suggestion is for you to explore the Assert class in more depth. There are many assertions available. The ones we’ve explored barely scratch the surface, despite being some of the most important ones. The more you master the Assert class, the more expressive your unit tests will be.

Thanks for reading!

This post was written by Carlos Schults. Carlos is a consultant and software engineer with experience in desktop, web, and mobile development. Though his primary language is C#, he has experience with a number of languages and platforms. His main interests include automated testing, version control, and code quality.