英文:
assertThatThrownBy() check field on custom exception
问题
以下是翻译好的内容:
如何使用 assertJ 检查自定义异常中特定字段的值?
以下是异常类:
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;
    }
}
以下是我的测试:
assertThatThrownBy(() -> service.doSomething())
    .isInstanceOf(SomeException.class)
    .hasMessageStartingWith("SomeException has 1,2,3,4 in something field. I want assert that")
    . ??? 检查 SomeException.getSomething() 是否有 1,2,3,4 ???
问题在于,如果我链式使用 extracting(),它会认为我在使用 Throwable。所以我不能提取 something 字段。
更新:
SomeException throwable = (SomeException) catchThrowable(() -> service.doSomething());
assertThat(throwable)
    .hasMessageStartingWith("extracting() 以下仍然认为我们在处理 Throwable")
    .extracting(SomeException::getSomething) <<<--- 这里无法工作
我尝试过以下操作,如下方建议:
assertThat(throwable)
    .hasMessageStartingWith("除了 containsExactlyInAnyOrder() 之外都有效")
    .asInstanceOf(InstanceOfAssertFactories.type(SomeException.class))
    .extracting(SomeException::getSomething)
    .---containsExactlyInAnyOrder<<<--- 不起作用!!!
但我不能再使用 containsExactlyInAnyOrder() 了 ![]()
请给予建议。
英文:
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
答案1
得分: 19
好的,以下是翻译好的内容:
似乎您正在寻找catchThrowableOfType,它允许您接收正确的类:
import static org.assertj.core.api.Assertions.catchThrowableOfType;
SomeException throwable = catchThrowableOfType(() -> service.doSomething(), SomeException.class);
assertThat(throwable.getSomething()).isNotNull();
英文:
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();
答案2
得分: 14
有许多关于“extracting”的变体,您想要使用的是extracting(String),例如:
   assertThatThrownBy(() -> service.doSomething())
        .isInstanceOf(SomeException.class)
        .hasMessageStartingWith("SomeException ... ")
        .extracting("something")
        .isEqualTo(1, 2, 3, 4);
使用extracting(String, InstanceOfAssertFactory)来获取专门的断言,所以如果值是一个集合,您可以尝试:
   assertThatThrownBy(() -> service.doSomething())
        .isInstanceOf(SomeException.class)
        .hasMessageStartingWith("SomeException ... ")
        .extracting("something", InstanceOfAssertFactories.ITERABLE)
        .contains();
您还可以尝试:hasFieldOrPropertyWithValue
更新: 工作示例
SomeException throwable = new SomeException("foo", Sets.newSet(1, 2, 3, 4));
assertThat(throwable).hasMessageStartingWith("fo")
                     .extracting("something", InstanceOfAssertFactories.ITERABLE)
                     .containsExactly(1, 2, 3, 4);
英文:
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);
答案3
得分: 1
我可能会这样做:
assertThatThrownBy(() -> service.doSomething())
    .isInstanceOf(SomeException.class)
    .hasMessageStartingWith("SomeException occurred")
    .isEqualToComparingFieldByField(
        new SomeException("", Sets.newHashSet(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.
答案4
得分: 0
替代extracting方法的方法是在matches或者satisfies方法中捕获异常:
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);
  });  
英文:
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);
  });  
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论