Explain Codes LogoExplain Codes Logo

How do I assert an Iterable contains elements with a certain property?

java
assertions
hamcrest
assertj
Alex KataevbyAlex Kataev·Nov 30, 2024
TLDR

Verify an element property within an Iterable using the anyMatch from Stream API coupled with AssertJ's assertThat.

import static org.assertj.core.api.Assertions.assertThat; boolean hasProperty = StreamSupport.stream(yourIterable.spliterator(), false) .anyMatch(item -> item.checkProperty()); assertThat(hasProperty).isTrue();

Swap checkProperty() with your actual property condition to test each item in yourIterable.

Using Hamcrest for Assertions

Hamcrest turns the art of assertion in Java into a breeze. With its clean, human-readable style, you can assert a property within an Iterable:

// Hamcrest piscine swim club import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; List<YourObject> wondersList = // ... summon your list; // Come on, hasItem! I bet my loot you have it! assertThat(wondersList, hasItem(hasProperty("name", is("expectedValue"))));

It's like magic! hasProperty conjures the seemingly impossible, checking the "name" property for a match with "expectedValue".

AssertJ: Fluent Assertions in Action

AssertJ does the heavy lifting when ensuring property assertions are as smooth as a hot knife through butter:

import static org.assertj.core.api.Assertions.assertThat; List<YourObject> wondersList = // ... summon your list again; // Knock, knock! Who's there? Just 'expectedValue', checking in. assertThat(wondersList).extracting("name").contains("expectedValue");

AssertJ's extracting cleanly retrieves your "name" properties from YourObject and its trusty companion contains verifies if "expectedValue" is part of the party.

Multi-faceted AssertJ Techniques

Checking multiple properties with tuples

When you're playing double agent and need to assert multiple properties, AssertJ's tuple function swoops in to the rescue:

// Order, order in the tuple court! assertThat(wondersList).extracting("name", "age") .contains(tuple("expectedName", expectedAge));

It's like a two-for-one torture device: concise and precise, keeping all your test detail under lock and key.

Asserting regardless of order

For cases where chaos rules and order doesn't matter, we enlist the help of AssertJ's containsExactlyInAnyOrder:

// Mmm... mixed fruit salad, my taste buds are tingling! assertThat(wondersList).extracting("name") .containsExactlyInAnyOrder("name1", "name2", "name3");

Verifying collection size

Make sure to take a headcount before running off:

// Line up, children, let's make sure we have everyone! assertThat(wondersList).hasSize(expectedSize);

This ensures that you avoid false positives – those sneaky hobbitses where the property exists but not in the right amount.

Checks that survive refactoring

Using method references instead of fumbling with string literals, makes for a safer and refactor-friendly vibe:

// The good, the refactor, and the broken test. assertThat(wondersList).extracting(YourObject::getName) .contains("expectedValue");

Say goodbye to the wild goose chase when property names take a hit during refactoring.

Java 8 Streams: Checking properties

Java 8 Streams offer a cool and effective way to filter and match elements:

// Hey there, yellow fellow; stop hiding! boolean hasYellowFruit = fruits.stream() .anyMatch(fruit -> "yellow".equals(fruit.getColor())); assertThat(hasYellowFruit).isTrue();

The simplicity and elegance of lambda expressions used here make your code feel like a poem – easy on the eyes and calming to the nerves.

Improve code readability with static imports

Install a no-scroll policy on your code with static imports, particularly when playing around with AssertJ:

// AssertJ FTW! import static org.assertj.core.api.Assertions.assertThat; // Unleash more static imports... // Hey 'assertThat', nice to see you here!

Probing Beyond Basic Properties

Diving into nested properties

Deep-diving into nested objects or collections within collections, all the glory goes to flatExtracting:

// Time to go inception level deep. assertThat(wondersList) .flatExtracting(YourObject::getSubObjects) .extracting(SubObject::getName) .contains("expectedSubObjectName");

Validating multiple conditions

Multiple conditions to validate? Just wrap them up nicely with AssertJ's allSatisfy method:

// AssertJ handles my multi-condition chaos effortlessly assertThat(wondersList).allSatisfy(object -> { assertThat(object.getName()).isNotEmpty(); assertThat(object.getAge()).isGreaterThan(18); });