I’m testing a Message object that contains a MessageHeaders field. The MessageHeaders class implements Map<String, Object>, and I want to assert that certain headers are set.
Here’s what I tried:
assertThat(actual)
.extracting(Message::getHeaders)
.containsKeys("someKey");
However, .extracting() returns an AbstractObjectAssert, so I can’t use MapAssert methods like containsKeys().
Is there a way to use AssertJ asInstanceOf or another AssertJ feature to cast the extracted field to a Map and then run assertions like containsKeys()?
I ran into the exact same issue when working with Spring’s MessageHeaders. The trick is to tell AssertJ to treat the extracted object as a Map using asInstanceOf.
Here’s how I handled it:
assertThat(actual)
.extracting(Message::getHeaders)
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsKeys("someKey");
Using assertj asInstanceOf with InstanceOfAssertFactories.MAP basically tells AssertJ, " Hey, this object is a Map, give me Map assertions.” It works perfectly for headers or any extracted map-like .
I faced this when testing Kafka message headers , AssertJ didn’t automatically switch to MapAssert.
What worked for me was chaining .asInstanceOf(InstanceOfAssertFactories.MAP) right after extracting.
assertThat(actual)
.extracting(Message::getHeaders)
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsEntry("someKey", "someValue");
The key here is that assertj asInstanceOf bridges the gap between object assertions and specialized assertions like MapAssert. It’s much cleaner than manual casting.
Yeah, AssertJ doesn’t auto-detect collection types after extracting(). I ended up solving it using the assertj asInstanceOf method and the InstanceOfAssertFactories helper.
Try this pattern:
assertThat(actual)
.extracting(Message::getHeaders)
.asInstanceOf(InstanceOfAssertFactories.MAP)
.containsKeys("someKey", "anotherKey");
It keeps the chain fluent and lets you use all the MapAssert goodies like containsKeys, containsEntry, etc. Much better than casting manually!