断言包含字段的特定异常

Assertion of Particular Exception which contains a field

目前我有一个测试试图检查一个看起来像这样的特定异常:

assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
        () -> xrepo.save(abc))
    .withCauseExactlyInstanceOf(ConstraintViolationException.class);

异常 ConstraintViolationException 有一个字段 constraintName 可通过 getter getConstraintName() 获得,但我还没有找到通过 assertj 进行检查的方法。

我可以想象如下:

assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
        () -> xrepo.save(abc))
    .withCauseExactlyInstanceOf(ConstraintViolationException.class)
    .with("getConstraintName").isEqualTo("XXXX");

或者是否有不同的方法来完成此操作?

可能是:

.extracting(x -> ((ConstraintViolationException)x).getConstraintName())
.isEqualTo("XXXX");

withCauseExactlyInstanceOf 不会改变被测对象,但是 havingCause() 可以对原因进行进一步的断言。

结合 asInstanceOf() and returns(),类型安全检查将是:

assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
        () -> xrepo.save(abc))
    .havingCause()
    .asInstanceOf(type(ConstraintViolationException.class))
    .returns("XXXX", from(ConstraintViolationException::getConstraintName));

或者没有类型安全,使用 isInstanceOf and hasFieldOrPropertyWithValue:

assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
        () -> xrepo.save(abc))
    .havingCause()
    .isInstanceOf(ConstraintViolationException.class)
    .hasFieldOrPropertyWithValue("getConstraintName", "XXX")

@Eugene 的解决方案给我带来了方向:

assertThatExceptionOfType(DataIntegrityViolationException.class).isThrownBy(
        () -> xyrepository.save(xxx))
    .withCauseExactlyInstanceOf(ConstraintViolationException.class)
    .extracting(s -> ((ConstraintViolationException) (s.getCause())).getConstraintName())
    .isEqualTo("XXXX");

@StefanoCordio 的解决方案看起来也不错...