Introduction
AssertJ is a fluent assertion library for Java that provides a rich set of assertions and a fluent API to improve the readability and maintainability of tests. AssertJ can be used with any testing framework like JUnit or TestNG. This guide will cover the installation, basic usage, advanced features, and complex examples using AssertJ, including detailed explanations of all important assertions.
Installation
To use AssertJ, add the following dependency to your pom.xml
if you're using Maven:
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.24.2</version> <!-- or the latest version -->
<scope>test</scope>
</dependency>
For Gradle:
dependencies {
testImplementation 'org.assertj:assertj-core:3.24.2' // or the latest version
}
Basic Usage
AssertJ with JUnit
Example: Basic Assertions
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class BasicAssertionsTest {
@Test
public void testBasicAssertions() {
String name = "Amit";
int age = 30;
assertThat(name).isEqualTo("Amit");
assertThat(age).isGreaterThan(20).isLessThan(40).isEqualTo(30);
}
}
Output
Test passed
Important AssertJ Assertions
Basic Assertions
isEqualTo()
Asserts that the actual value is equal to the expected value.
@Test
public void testIsEqualTo() {
String name = "Anil";
assertThat(name).isEqualTo("Anil");
}
isNotEqualTo()
Asserts that the actual value is not equal to the expected value.
@Test
public void testIsNotEqualTo() {
String name = "Anil";
assertThat(name).isNotEqualTo("Vikas");
}
String Assertions
contains()
Asserts that the actual string contains the given sequence.
@Test
public void testContains() {
String sentence = "Anil is a software engineer";
assertThat(sentence).contains("software");
}
doesNotContain()
Asserts that the actual string does not contain the given sequence.
@Test
public void testDoesNotContain() {
String sentence = "Anil is a software engineer";
assertThat(sentence).doesNotContain("doctor");
}
startsWith()
Asserts that the actual string starts with the given prefix.
@Test
public void testStartsWith() {
String sentence = "Anil is a software engineer";
assertThat(sentence).startsWith("Anil");
}
endsWith()
Asserts that the actual string ends with the given suffix.
@Test
public void testEndsWith() {
String sentence = "Anil is a software engineer";
assertThat(sentence).endsWith("engineer");
}
isEmpty()
Asserts that the actual string is empty.
@Test
public void testIsEmpty() {
String emptyString = "";
assertThat(emptyString).isEmpty();
}
Collection Assertions
hasSize()
Asserts that the actual collection has the given size.
@Test
public void testHasSize() {
List<String> names = List.of("Arjun", "Priya", "Lakshmi");
assertThat(names).hasSize(3);
}
contains()
Asserts that the actual collection contains the given values.
@Test
public void testContains() {
List<String> names = List.of("Arjun", "Priya", "Lakshmi");
assertThat(names).contains("Priya", "Lakshmi");
}
doesNotContain()
Asserts that the actual collection does not contain the given values.
@Test
public void testDoesNotContain() {
List<String> names = List.of("Arjun", "Priya", "Lakshmi");
assertThat(names).doesNotContain("Ravi");
}
containsExactly()
Asserts that the actual collection contains exactly the given values in the given order.
@Test
public void testContainsExactly() {
List<String> names = List.of("Arjun", "Priya", "Lakshmi");
assertThat(names).containsExactly("Arjun", "Priya", "Lakshmi");
}
Map Assertions
hasSize()
Asserts that the actual map has the given size.
@Test
public void testHasSize() {
Map<String, Integer> ageMap = Map.of("Rohit", 28, "Sneha", 25, "Vikas", 35);
assertThat(ageMap).hasSize(3);
}
containsKeys()
Asserts that the actual map contains the given keys.
@Test
public void testContainsKeys() {
Map<String, Integer> ageMap = Map.of("Rohit", 28, "Sneha", 25, "Vikas", 35);
assertThat(ageMap).containsKeys("Rohit", "Sneha");
}
containsValues()
Asserts that the actual map contains the given values.
@Test
public void testContainsValues() {
Map<String, Integer> ageMap = Map.of("Rohit", 28, "Sneha", 25, "Vikas", 35);
assertThat(ageMap).containsValues(25, 35);
}
doesNotContainKeys()
Asserts that the actual map does not contain the given keys.
@Test
public void testDoesNotContainKeys() {
Map<String, Integer> ageMap = Map.of("Rohit", 28, "Sneha", 25, "Vikas", 35);
assertThat(ageMap).doesNotContainKeys("Amit");
}
doesNotContainValue()
Asserts that the actual map does not contain the given value.
@Test
public void testDoesNotContainValue() {
Map<String, Integer> ageMap = Map.of("Rohit", 28, "Sneha", 25, "Vikas", 35);
assertThat(ageMap).doesNotContainValue(40);
}
Object Assertions
isNotNull()
Asserts that the actual object is not null.
@Test
public void testIsNotNull() {
String name = "Anil";
assertThat(name).isNotNull();
}
isNull()
Asserts that the actual object is null.
@Test
public void testIsNull() {
String name = null;
assertThat(name).isNull();
}
isInstanceOf()
Asserts that the actual object is an instance of the given class.
@Test
public void testIsInstanceOf() {
String name = "Anil";
assertThat(name).isInstanceOf(String.class);
}
Boolean Assertions
isTrue()
Asserts that the actual boolean value is true.
@Test
public void testIsTrue() {
boolean isActive = true;
assertThat(isActive).isTrue();
}
isFalse()
Asserts that the actual boolean value is false.
@Test
public void testIsFalse() {
boolean isActive = false;
assertThat(isActive).isFalse();
}
Numeric Assertions
isGreaterThan()
Asserts that the actual number is greater than the given number.
@Test
public void testIsGreaterThan() {
int age = 30;
assertThat(age).isGreaterThan(20);
}
isLessThan()
Asserts that the actual number is less than the given number.
@Test
public void testIsLessThan() {
int age = 30;
assertThat(age).isLessThan(40);
}
isBetween()
Asserts that the actual number is between the given start and end values (inclusive).
@Test
public void testIsBetween() {
int age = 30;
assertThat(age).isBetween(20, 40);
}
Date and Time Assertions
isBefore()
Asserts that the actual date is before the given date.
@Test
public void testIsBefore() {
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
assertThat(today).isBefore(tomorrow);
}
isAfter()
Asserts that the actual date is after the given date.
@Test
public void testIsAfter() {
LocalDate today = LocalDate.now();
LocalDate yesterday = today.minusDays(1);
assertThat(today).isAfter(yesterday);
}
isEqualTo()
Asserts that the actual date is equal to the given date.
@Test
public void testIsEqualTo() {
LocalDate today = LocalDate.now();
assertThat(today).isEqualTo(LocalDate.now());
}
Exception Assertions
isThrownBy()
Asserts that the given exception is thrown by the provided code.
@Test
public void testIsThrownBy() {
assertThatThrownBy(() -> {
throw new IllegalArgumentException("Invalid argument");
}).isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid argument");
}
Soft Assertions
Soft assertions allow multiple assertions to be executed, collecting all failures to be reported at the end.
@Test
public void testSoftAssertions() {
SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThat("Amit").isEqualTo("Amit");
softAssertions.assertThat(25).isGreaterThan(20);
softAssertions.assertThat(false).isTrue(); // This will fail
softAssertions.assertThat("Lakshmi").isNotEmpty();
softAssertions.assertAll(); // This will report all failures
}
BDD Assertions
BDD-style assertions using the then
syntax for behavior-driven development.
@Test
public void testBddAssertions() {
String name = "Lakshmi";
int age = 27;
then(name).isEqualTo("Lakshmi");
then(age).isBetween(25, 30);
}
Output
Test passed
Advanced Features
Collection Assertions
AssertJ provides a rich set of assertions for collections.
Example: List Assertions
@Test
public void testListAssertions() {
List<String> names = List.of("Arjun", "Priya", "Lakshmi");
assertThat(names)
.hasSize(3)
.contains("Priya")
.doesNotContain("Ravi")
.startsWith("Arjun")
.endsWith("Lakshmi");
}
Output
Test passed
Map Assertions
Example: Map Assertions
@Test
public void testMapAssertions() {
Map<String, Integer> ageMap = Map.of("Rohit", 28, "Sneha", 25, "Vikas", 35);
assertThat(ageMap)
.hasSize(3)
.containsKeys("Rohit", "Sneha")
.containsValues(25, 35)
.doesNotContainKeys("Amit")
.doesNotContainValue(40);
}
Output
Test passed
Custom Assertions
You can create custom assertions by extending AbstractAssert
.
Example: Custom Assertion for a User Class
import org.assertj.core.api.AbstractAssert;
public class UserAssert extends AbstractAssert<UserAssert, User> {
public UserAssert(User user) {
super(user, UserAssert.class);
}
public static UserAssert assertThatUser(User user) {
return new UserAssert(user);
}
public UserAssert hasName(String name) {
isNotNull();
if (!actual.getName().equals(name)) {
failWithMessage("Expected user's name to be %s but was %s", name, actual.getName());
}
return this;
}
public UserAssert hasAge(int age) {
isNotNull();
if (actual.getAge() != age) {
failWithMessage("Expected user's age to be %d but was %d", age, actual.getAge());
}
return this;
}
}
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
@Test
public void testCustomAssertions() {
User user = new User("Sita", 22);
UserAssert.assertThatUser(user).hasName("Sita").hasAge(22);
}
Output
Test passed
Exception Assertions
AssertJ provides a fluent API for asserting exceptions.
Example: Exception Assertions
@Test
public void testExceptionAssertions() {
assertThatThrownBy(() -> { throw new IllegalArgumentException("Invalid argument"); })
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Invalid argument");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> { throw new IllegalArgumentException("Invalid argument"); })
.withMessage("Invalid argument");
}
Output
Test passed
Soft Assertions
Soft assertions allow you to execute multiple assertions and report all failures at the end.
Example: Soft Assertions
@Test
public void testSoftAssertions() {
SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThat("Ravi").isEqualTo("Ravi");
softAssertions.assertThat(30).isGreaterThan(20);
softAssertions.assertThat(true).isFalse(); // This will fail
softAssertions.assertThat("Amit").isNotEmpty();
softAssertions.assertAll(); // This will report all failures
}
Output
SoftAssertionsTest.testSoftAssertions: Soft assertion errors:
1) expected:<[fals]e> but was:<[tru]e>
BDD Assertions
AssertJ supports BDD-style assertions using the assertThat
syntax.
Example: BDD Assertions
@Test
public void testBddAssertions() {
String name = "Lakshmi";
int age = 27;
then(name).isEqualTo("Lakshmi");
then(age).isBetween(25, 30);
}
Output
Test passed
Extracting and Filtering
AssertJ provides powerful methods for extracting and filtering collections.
Example: Extracting and Filtering
@Test
public void testExtractingFiltering() {
List<User> users = List.of(
new User("Rahul", 25),
new User("Meera", 30),
new User("Vijay", 35)
);
assertThat(users)
.extracting("name", "age")
.contains(tuple("Rahul", 25), tuple("Meera", 30))
.doesNotContain(tuple("Amit", 40));
assertThat(users)
.filteredOn(user -> user.getAge() > 30)
.containsExactly(new User("Vijay", 35));
}
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && name.equals(user.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
Output
Test passed
Complex Examples
Example: Complex Object Assertions
Let's consider a complex object with nested properties and assert its various attributes.
@Test
public void testComplexObjectAssertions() {
Address address = new Address("123 Main St", "Chennai", "600001");
User user = new User("Kiran", 30, address, List.of("Admin", "User"));
assertThat(user)
.extracting("name", "age")
.containsExactly("Kiran", 30);
assertThat(user.getAddress())
.extracting("street", "city", "zipCode")
.containsExactly("123 Main St", "Chennai", "600001");
assertThat(user.getRoles())
.contains("Admin", "User")
.doesNotContain("Guest");
}
class User {
private String name;
private int age;
private Address address;
private List<String> roles;
public User(String name, int age, Address address, List<String> roles) {
this.name = name;
this.age = age;
this.address = address;
this.roles = roles;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Address getAddress() {
return address;
}
public List<String> getRoles() {
return roles;
}
}
class Address {
private String street;
private String city;
private String zipCode;
public Address(String street, String city, String zipCode) {
this.street = street;
this.city = city;
this.zipCode = zipCode;
}
public String getStreet() {
return street;
}
public String getCity() {
return city;
}
public String getZipCode() {
return zipCode;
}
}
Output
Test passed
Example: Soft Assertions for Complex Objects
Using soft assertions to verify multiple attributes of complex objects.
@Test
public void testSoftAssertionsComplex() {
SoftAssertions softAssertions = new SoftAssertions();
Address address = new Address("456 Park Ave", "Mumbai", "400001");
User user = new User("Aarti", 28, address, List.of("User", "Editor"));
softAssertions.assertThat(user.getName()).isEqualTo("Aarti");
softAssertions.assertThat(user.getAge()).isEqualTo(28);
softAssertions.assertThat(user.getAddress().getCity()).isEqualTo("Mumbai");
softAssertions.assertThat(user.getRoles()).contains("User
", "Editor");
softAssertions.assertAll(); // This will report all failures
}
Output
Test passed
Example: Custom Assertions with Nested Objects
Creating custom assertions for complex nested objects.
public class CustomNestedAssertionsTest {
@Test
public void testCustomNestedAssertions() {
Address address = new Address("789 Hill St", "Pune", "411001");
User user = new User("Anil", 35, address, List.of("Admin", "User"));
UserAssert.assertThatUser(user)
.hasName("Anil")
.hasAge(35)
.hasAddress("789 Hill St", "Pune", "411001")
.hasRoles("Admin", "User");
}
}
class UserAssert extends AbstractAssert<UserAssert, User> {
public UserAssert(User user) {
super(user, UserAssert.class);
}
public static UserAssert assertThatUser(User user) {
return new UserAssert(user);
}
public UserAssert hasName(String name) {
isNotNull();
if (!actual.getName().equals(name)) {
failWithMessage("Expected user's name to be %s but was %s", name, actual.getName());
}
return this;
}
public UserAssert hasAge(int age) {
isNotNull();
if (actual.getAge() != age) {
failWithMessage("Expected user's age to be %d but was %d", age, actual.getAge());
}
return this;
}
public UserAssert hasAddress(String street, String city, String zipCode) {
isNotNull();
Address address = actual.getAddress();
if (!address.getStreet().equals(street) || !address.getCity().equals(city) || !address.getZipCode().equals(zipCode)) {
failWithMessage("Expected address to be %s, %s, %s but was %s, %s, %s", street, city, zipCode,
address.getStreet(), address.getCity(), address.getZipCode());
}
return this;
}
public UserAssert hasRoles(String... roles) {
isNotNull();
assertThat(actual.getRoles()).containsExactly(roles);
return this;
}
}
class User {
private String name;
private int age;
private Address address;
private List<String> roles;
public User(String name, int age, Address address, List<String> roles) {
this.name = name;
this.age = age;
this.address = address;
this.roles = roles;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Address getAddress() {
return address;
}
public List<String> getRoles() {
return roles;
}
}
class Address {
private String street;
private String city;
private String zipCode;
public Address(String street, String city, String zipCode) {
this.street = street;
this.city = city;
this.zipCode = zipCode;
}
public String getStreet() {
return street;
}
public String getCity() {
return city;
}
public String getZipCode() {
return zipCode;
}
}
Output
Test passed
Conclusion
AssertJ is a powerful and flexible assertion library for Java that improves the readability and maintainability of tests. This tutorial covered the basics of AssertJ, including basic assertions, string assertions, collection assertions, map assertions, object assertions, boolean assertions, numeric assertions, date and time assertions, exception assertions, soft assertions, and BDD assertions. Additionally, we explored complex examples such as custom assertions for nested objects and soft assertions for complex objects. By leveraging AssertJ, you can enhance your testing capabilities and ensure the quality and reliability of your Java applications. For more detailed information and advanced features, refer to the official AssertJ documentation.
Comments
Post a Comment
Leave Comment