`assertThatThrownBy()` 检查自定义异常上的字段。

huangapple go评论138阅读模式
英文:

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() 了 `assertThatThrownBy()` 检查自定义异常上的字段。

请给予建议。

英文:

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&lt;Integer&gt; something;

    public SomeException (String message, Set&lt;Integer&gt; something) {
        super(message);

        this.something = something;
    }

    public Set&lt;Integer&gt; getSomething() {
        return something;
    }
}

Here is my test:

    assertThatThrownBy(() -&gt; service.doSomething())
        .isInstanceOf(SomeException.class)
        .hasMessageStartingWith(&quot;SomeException has 1,2,3,4 in something field. I want assert that&quot;)
        . ??? 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(() -&gt; service.doSomething(

assertThat(throwable)
    .hasMessageStartingWith(&quot;extracting() bellow still think we&#39;re working with Throwable&quot;)
    .extracting(SomeException::getSomething &lt;&lt;&lt;--- doesn&#39;t work here)

I have tried following, as suggested bellow:

 assertThat(throwable)
        .hasMessageStartingWith(&quot;Works except containsExactlyInAnyOrder()&quot;)
        .asInstanceOf(InstanceOfAssertFactories.type(SomeException.class))
        .extracting(SomeException::getSomething)
        .-&gt;&gt;&gt;containsExactlyInAnyOrder&lt;&lt;&lt;--- Not working!!!

But I can't use containsExactlyInAnyOrder() anymore `assertThatThrownBy()` 检查自定义异常上的字段。

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(() -&gt; 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(() -&gt; service.doSomething())
        .isInstanceOf(SomeException.class)
        .hasMessageStartingWith(&quot;SomeException ... &quot;)
        .extracting(&quot;something&quot;)
        .isEqualTo(1,2,3,4);

Use extracting(String, InstanceOfAssertFactory) to get specialized assertions, so if the value is a collection you can try:

   assertThatThrownBy(() -&gt; service.doSomething())
        .isInstanceOf(SomeException.class)
        .hasMessageStartingWith(&quot;SomeException ... &quot;)
        .extracting(&quot;something&quot;, InstanceOfAssertFactories.ITERABLE)
        .contains();

You can also try: hasFieldOrPropertyWithValue

Update: working example

SomeException throwable = new SomeException(&quot;foo&quot;, Sets.newSet(1, 2, 3, 4));

assertThat(throwable).hasMessageStartingWith(&quot;fo&quot;)
                     .extracting(&quot;something&quot;, 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(() -&gt; service.doSomething())
    .isInstanceOf(SomeException.class)
    .hasMessageStartingWith(&quot;SomeException occurred&quot;)
    .isEqualToComparingFieldByField(
        new SomeException(&quot;&quot;, 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(&quot;...&quot;)
  .matches(e -&gt; ((SomeException) e).getSomething().containsAll(elements);    
assertThat(throwable)
  .isInstanceOf(SomeException.class)
  .hasMessageStartingWith(&quot;...&quot;)
  .satisfies(e -&gt; {
    SomethingException somethingException = (SomethingException) e;

    assertThat(somethingException.getSomething()).contains(1, 2, 3, 4);
  });  

huangapple
  • 本文由 发表于 2020年10月27日 00:29:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/64541192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定