Test Assertions in Java the best way

Thiago Bomfim
3 min readJul 1, 2024

--

Unit testing is a technique to test the smaller pieces of code known as units. A good unit testing has a structure similar to it:

@Test
public void testSomeMethod() {
// Setup
MyClass myClass = new MyClass();

// Execution
int result = myClass.someMethod(2, 3);

// Assertion
assertEquals(5, result, "Expected result is incorrect.");

// Teardown (if necessary)
}

Let’s talk about Assertions, and how to create assertions in the best way.

AssertJ

If you are using Java, chances are you are using JUnit 5. JUnit 5 provides many possible assertions, however, it’s not very clean. The AssertJ library provides a more fluent way to create assertions.

AssertJ is a Java library to create fluent assertions, and it provides many ways to validate your test.

The fluent API provided by AssertJ makes it easy to read and use.

isEqualTo

The most common usage of AssertJ is to verify if the element is equalTo another element. We can do it by using the following method:

@org.junit.jupiter.api.Test
void testCalculateEmployeesSumSalary() {
CompanyService companyService = new CompanyService();
Company company = new Company(
List.of(
new Developer("James", BigDecimal.valueOf(5_000)),
new Manager("Jessie", BigDecimal.valueOf(8_000), BigDecimal.valueOf(2_000))
)
);
BigDecimal bigDecimal = companyService.calculateEmployeesSumSalary(company);
org.assertj.core.api.Assertions.assertThat(bigDecimal).isEqualTo(BigDecimal.valueOf(13_000));
}

isRecord

Since Java 16 we have Record in Java, which is an amazing feature. Did you know that it is possible to test whether your class is a record.

You can do it using the isRecord method.

@Test
void testCompanyType() {
org.assertj.core.api.Assertions.assertThat(Company.class).isRecord();
}

extracting & contains

If you have a list of objects, you can verify if this list contains some elements and also if it does not contain them. Not only that, but you can also extract things from your objects and test only a few elements.

@Test
void testEmployees() {
Company company = new Company(
List.of(
new Developer("James", BigDecimal.valueOf(5_000)),
new Manager("Jessie", BigDecimal.valueOf(8_000), BigDecimal.valueOf(2_000))
)
);
org.assertj.core.api.Assertions.assertThat(company.employees())
.extracting(Employee::getName)
.contains("James", "Jessie")
.doesNotContain("Ash");

}

Testing exceptions

Throwing an exception when a business rule is invalid is very common, but do you know that it is very easy to create a test for it?

We can use the assertThatThrownBy method.

@Test
void testDeveloperSalary() {
org.assertj.core.api.Assertions
.assertThatThrownBy(() -> new Developer("Brock", BigDecimal.valueOf(800)))
.isInstanceOf(InvalidSalaryException.class)
.hasMessage("The salary should be bigger than the minimum salary (1.000)");
}

SoftAssertions

If you have many assertions, you can also use the SoftAssertions to test all the assertions and give all the results at once.

@Test
void testDeveloperAttributes() {
Developer ashKetchum = new Developer("Ash Ketchum", BigDecimal.valueOf(2_000));
SoftAssertions.assertSoftly(s -> {
s.assertThat(ashKetchum.getSalary()).isEqualTo(BigDecimal.valueOf(2_000));
s.assertThat(ashKetchum.calculateNetSalary()).isEqualByComparingTo(BigDecimal.valueOf(1_500));
s.assertThat(ashKetchum.getName())
.startsWith("Ash")
.endsWith("Ketchum2");
});
}

The output of this execution will be 2 errors

java.lang.AssertionError: 
Expected :1500
Actual :1600.0

java.lang.AssertionError:
Expecting actual:
"Ash Ketchum"
to end with:
"Ketchum2"

Conclusion

AssertJ is an awesome library for fluently creating assertions, making it easy to read and use.

If you use another common assertion, please, share it here in the comments.

All the code is available here on my GitHub.

References

AssertJ — fluent assertions java library

--

--

Thiago Bomfim
Thiago Bomfim

Written by Thiago Bomfim

I'm a happy developer, trying to help the world and peoples with technologic

No responses yet