I am having this test, junit
assestion works well, while the same assertj
assertion does not.
@Test
void registerWithDuplicatedEmail() throws EmailAlreadyRegistered {
Mockito.when(customerCommand.createCustomer("Duplicated", "[email protected]", "pass"))
.thenThrow(new EmailAlreadyRegistered());
assertThrows(EmailAlreadyRegistered.class, () -> registerCustomerUseCase.execute("Duplicated", "[email protected]", "pass"));
// (1) this works well
assertThatCode(() -> registerCustomerUseCase.execute("Duplicated", "[email protected]", "pass")).hasCause(new EmailAlreadyRegistered());
// (2) This fails with the error:
// Expecting a cause with type: "...exception.EmailAlreadyRegistered" and message: null
// but actualCause had no cause.
assertThatCode(() -> registerCustomerUseCase.execute("Duplicated", "[email protected]", "pass")).doesNotThrowAnyException();
// (3) Although it contradicts the previous one, this also fails with this error:
// Expecting code not to raise a throwable but caught "...exception.EmailAlreadyRegistered"
assertThatExceptionOfType(EmailAlreadyRegistered.class).isThrownBy(() -> registerCustomerUseCase.execute("Duplicated", "[email protected]", "pass"));
// (4) This also works well
}
RegisterCustomerUseCase is pretty simple:
@Component
@RequiredArgsConstructor
public class RegisterCustomerUseCase {
private final CustomerCommand customerCommand;
public Customer execute(String name, String email, String password) throws EmailAlreadyRegistered {
return customerCommand.createCustomer(name, email, password);
}
}
Do you have any idea why cases (2) and (3) fail?
.hasCause
checks the cause (.getCause()
) of an exception, whereas assertThrows
checks the exception directly. Your exception does not have a cause and thus the test fails correctly.
You are looking for isInstanceOf
with the class (not an instance) as parameter:
assertThatCode(() -> registerCustomerUseCase.execute("Duplicated", "[email protected]", "pass"))
.isInstanceOf(EmailAlreadyRegistered.class);
Alternatively, assert with assertThatThrownBy
:
assertThatThrownBy(() -> registerCustomerUseCase.execute("Duplicated", "[email protected]", "pass"))
.isInstanceOf(EmailAlreadyRegistered.class);