AssertThatThrownBy() Check Field on Custom Exception
How Can I Check Particular Field Value in My Custom Excepiton Using assertJ? Here Is Exception Class: Public Class Someexception Extends Runtimeexception {...
How can I check particular field value in my custom excepiton using assertJ?
Here is exception class:
public class SomeException extends RuntimeException {
private final Set<Integer> something;
public SomeException (String message, Set<Integer> something) {
super(message);
this.something = something;
}
public Set<Integer> getSomething() {
return something;
}
}
Here is my test:
assertThatThrownBy(() -> service.doSomething())
.isInstanceOf(SomeException.class)
.hasMessageStartingWith("SomeException has 1,2,3,4 in something field. I want assert that")
. ??? check that SomeException.getSomething() has 1,2,3,4 ???
The problem is that if I chain extracting() it will think I'm using Throwable. So I can't extract field something
Update:
SomeException throwable = (SomeException) catchThrowable(() -> service.doSomething(
assertThat(throwable)
.hasMessageStartingWith("extracting() bellow still think we're working with Throwable")
.extracting(SomeException::getSomething <<<--- doesn't work here)
I have tried following, as suggested bellow:
assertThat(throwable)
.hasMessageStartingWith("Works except containsExactlyInAnyOrder()")
.asInstanceOf(InstanceOfAssertFactories.type(SomeException.class))
.extracting(SomeException::getSomething)
.->>>containsExactlyInAnyOrder<<<--- Not working!!!
But I can't use containsExactlyInAnyOrder() anymore :(
Please advise
4 Answers
It looks like you're looking for catchThrowableOfType, which allows you to receive the correct class:
import static org.assertj.core.api.Assertions.catchThrowableOfType;
SomeException throwable = catchThrowableOfType(() -> service.doSomething(), SomeException.class);
assertThat(throwable.getSomething()).isNotNull();
There are quite a few variations on extracting, the one you want to use is extracting(String), ex:
assertThatThrownBy(() -> service.doSomething())
.isInstanceOf(SomeException.class)
.hasMessageStartingWith("SomeException ... ")
.extracting("something")
.isEqualTo(1,2,3,4);
Use extracting(String, InstanceOfAssertFactory) to get specialized assertions, so if the value is a collection you can try:
assertThatThrownBy(() -> service.doSomething())
.isInstanceOf(SomeException.class)
.hasMessageStartingWith("SomeException ... ")
.extracting("something", InstanceOfAssertFactories.ITERABLE)
.contains();
You can also try: hasFieldOrPropertyWithValue
Update: working example
SomeException throwable = new SomeException("foo", Sets.newSet(1, 2, 3, 4));
assertThat(throwable).hasMessageStartingWith("fo")
.extracting("something", InstanceOfAssertFactories.ITERABLE)
.containsExactly(1, 2, 3, 4);
I'd do something like :
assertThatThrownBy(() -> service.doSomething())
.isInstanceOf(SomeException.class)
.hasMessageStartingWith("SomeException occurred")
.isEqualToComparingFieldByField(
new SomeException("", Sets.newHashSet(1,2,3,4)));
This way you don't have to worry about changing the field name in future because you're not hardcoding it anywhere in the assert statements.
An alternative to the extracting method would be to catch the exception in matches or satisfies method :
var elements = Set.of(1, 2, 3, 4);
assertThat(throwable)
.isInstanceOf(SomeException.class)
.hasMessageStartingWith("...")
.matches(e -> ((SomeException) e).getSomething().containsAll(elements);
assertThat(throwable)
.isInstanceOf(SomeException.class)
.hasMessageStartingWith("...")
.satisfies(e -> {
SomethingException somethingException = (SomethingException) e;
assertThat(somethingException.getSomething()).contains(1, 2, 3, 4);
});