我有这样一段代码,在更新到Assertj 3.16.1后,它不再工作了。
Throwable thrown = catchThrowable(() -> myObject.methodThrowsException());
assertThat(thrown).isInstanceOf(MyCustomException.class).extracting("fault").hasOnlyElementsOfType(CustomException.class).extracting("code").containsExactly("AnotherCustomException");
我得到这个错误信息。
java:cannot find symbol
symbol: method hasOnlyElementsOfType(java.lang.Class<CustomException.class>)
location: class org.assertj.core.api.AbstractObjectAssert<capture#1 of?, capture#2 of ?>
要么是它被废弃了,要么是现在的实现方式不同了。我已经翻阅了文档,并搜索了近两天,想看看是否有任何关于如何使用它与之前的使用方式不同的信息,以实现轻松过渡,但还没有找到任何信息。其实我在使用这个的时候也会出现类似的错误。containsOnlyOnceElementsOf
以代替给出问题的那个。有没有其他方法可以替代这些方法,达到同样的目的?
任何帮助将被感激!!!
看来你是从AssertJ 3.12或更早的版本升级的。
错误是 AbstractObjectAssert
类没有 hasOnlyElementsOfType
方法。此外,它还 从来没有 有这个方法,所以并不是这个方法被废弃和删除了。相反,这段代码一定是有效的,因为 hasOnlyElementsOfType
被其他类调用。
在AssertJ中,大多数事情似乎都要经过 AbstractObjectAssert
. 审视 AbstractObjectAssert
在AssertJ 3.12中,我看到它有一个方法是 extracting(String...)
-- 一个varargs方法,返回 AbstractListAssert
. 这个类又有一个 hasOnlyElementsOfType
方法继承自 AbstractIterableAssert
. 编码 extracting("fault")
最终成为一个varargs调用。这反过来又返回 AbstractListAssert
因此,随后呼吁 hasOnlyElementsOfType
工作。
然而,在AssertJ 3.13中。AbstractObjectAssert
有一个新的方法 extracting(String)
-- 不 一个varargs调用。该方法返回 AbstractObjectAssert
正如我们所看到的那样,它不具有 hasOnlyElementsOfType
方法。当针对这个版本的AssertJ(或更高版本)进行编译时,代码中的 extracting("fault")
解析为单参数过载。这将返回 AbstractObjectAssert
其中 不 拥有 hasOnlyElementsOfType
方法,因此出现错误。
为了解决这个问题,你可以强制调用到 extracting
来调用varargs重载而不是one-arg重载。varargs 调用只是在该位置传递数组的一些语法,所以你可以把你的代码改成这样。
....extracting(new String[] { "fault" })....
这最终会调用varargs重载,它将返回 AbstractListAssert
,它具有 hasOnlyElementsOfType
方法,所以即使在最近的AssertJ版本中也能正常工作。
作为一个旁白,这是一个相当罕见的添加方法导致不兼容的例子。通常情况下,添加方法不会影响任何现有的代码。然而,在现有的API中添加一个新的重载(就像AssertJ在3.13中所做的那样)可能会影响现有源代码的重载解析。也就是说,现有的针对旧版本编译的源代码最终会调用一些方法。当同样的源代码被编译到新版本时,它可能最终会调用新API中的一个不同的方法。如果这个新方法有不同的行为,可能会导致微妙的bug。在这种情况下,新方法有不同的返回类型,所以期望旧返回类型的代码不再工作。这正是这里发生的事情。
Stuart Marks在纯AssertJ方面发了一篇很好的分析,没什么好补充的了 extracting(String)
只提取一个值,这意味着你只能用链式对象断言而不是列表断言(这是有道理的,因为你提取了一个值)。
我相信你可以做以下断言。
assertThat(thrown).isInstanceOf(MyCustomException.class)
.extracting("fault")
.isInstanceOf(CustomException.class)
.extracting("code")
.isEqualTo("AnotherCustomException");