如何在junit测试用例中的列表之间进行相等Assert?列表内容之间应该相等。
例如:
List<String> numbers = Arrays.asList("one", "two", "three");
List<String> numbers2 = Arrays.asList("one", "two", "three");
List<String> numbers3 = Arrays.asList("one", "two", "four");
// numbers should be equal to numbers2
//numbers should not be equal to numbers3
14条答案
按热度按时间qjp7pelc1#
assertEquals(Object, Object)
来自junit4/JUnit5或assertThat(actual, is(expected));
从汉克雷斯特提出的其他答案只能作为两者equals()
以及toString()
为比较对象的类(和深度)重写。这很重要,因为Assert中的相等性测试依赖于
equals()
测试失败消息依赖于toString()
比较对象的。对于内置类,例如
String
,Integer
所以。。。没问题,因为这两个都会覆盖equals()
以及toString()
. 所以Assert是完全正确的List<String>
或者List<Integer>
与assertEquals(Object,Object)
.关于这件事:你必须推翻
equals()
因为它在对象相等性方面是有意义的,而不仅仅是在junit测试中使Assert更容易。为了使Assert更容易,你有其他的方法。
作为一个好的实践,我倾向于Assert/匹配器库。
这里有一个assertj解决方案。
org.assertj.core.api.ListAssert.containsExactly()
是您所需要的:它验证实际组是否完全包含给定的值,而不包含任何其他内容,顺序如javadoc中所述。假设一个
Foo
类在何处添加元素以及在何处可以获得这些元素。单元测试
Foo
Assert这两个列表具有相同的内容可能如下所示:资产的一个优点是
List
正如预期的那样是不必要的:它使Assert更直接,代码更可读:但是Assert/匹配器库是必须的,因为它们将真正进一步。
现在假设
Foo
不存储String
但是Bar
的示例。这是一个非常普遍的需要。使用assertj,Assert仍然很容易编写。更好的是,即使元素的类没有重写,也可以Assert列表内容是相等的
equals()/hashCode()
junit way要求:bn31dyow2#
如果你不想建立一个数组列表,你也可以试试这个
rnmwe5a23#
不要转换为字符串并进行比较。这不利于表现。在junit中,corematchers内部有一个匹配器
hasItems
```List yourList = Arrays.asList(1,2,3,4)
assertThat(yourList, CoreMatchers.hasItems(1,2,3,4,5));
kxeu7u2r4#
这是一个遗留的答案,适用于JUnit4.3及以下版本。junit的现代版本在assertthat方法中包含内置的可读失败消息。如果可能的话,更喜欢这个问题的其他答案。
作为记录,正如@paul在对这个答案的评论中提到的,两个
List
s等于:当且仅当指定的对象也是一个列表时,两个列表具有相同的大小,并且两个列表中所有对应的元素对都相等(两个要素
e1
以及e2
如果(e1==null ? e2==null : e1.equals(e2))
换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals方法在List
接口。请参阅
List
接口。6tdlim6h5#
您可以在junit中使用assertequals。
如果元素的顺序不同,则返回错误。
如果您正在Assert一个模型对象列表,那么您应该重写特定模型中的equals方法。
nkkqxpd96#
我知道已经有很多方法可以解决这个问题,但我更愿意按以下步骤在任何顺序Assert两个列表:
2cmtqfgy7#
如果你不关心元素的顺序,我建议
ListAssert.assertEquals
在junit插件中。链接:http://junit-addons.sourceforge.net/
对于懒惰的maven用户:
5anewei68#
assertEquals(expected, result);
对我有用。因为这个函数有两个对象,所以可以传递任何东西给它。5m1hhzi49#
为了junit4!这个问题值得为junit5写一个新的答案。
我意识到这个答案是在问题出现几年后写的,可能这个功能当时并不存在。但现在,很容易做到这一点:
如果您在hamcrest中安装了junit的最新版本,只需添加以下导入:
http://junit.org/junit4/javadoc/latest/org/junit/assert.html#assertthat(t,org.hamcrest.matcher)
http://junit.org/junit4/javadoc/latest/org/hamcrest/corematchers.html
http://junit.org/junit4/javadoc/latest/org/hamcrest/core/is.html
ej83mcc010#
我不知道以上所有的答案都给出了比较两个对象列表的精确解。上述大多数方法都有助于遵循比较的极限-规模比较-参考比较
但是,如果我们有相同大小的对象列表和对象级别上不同的数据,那么这种比较方法就没有帮助了。
我认为下面的方法可以很好地在用户定义的对象上重写equals和hashcode方法。
我使用xstream lib重写equals和hashcode,但是我们也可以通过out-won逻辑/比较来重写equals和hashcode。
这是一个例子供你参考
最重要的是,如果不想在对象的相等检查中包含任何字段,则可以通过注解忽略字段(@xstreamitfield)。有许多这样的注解需要配置,所以请深入了解这个库的注解。
我相信这个答案将节省您确定比较两个对象列表的正确方法的时间:)。请评论,如果你看到这方面的任何问题。
w8ntj3qf11#
vngu2lb812#
对于junit 5
你可以用
assertIterableEquals
:或者
assertArrayEquals
以及将列表转换为数组:bfhwhh0e13#
不要重新发明轮子!
有一个google代码库可以帮你做到这一点:hamcrest
[hamcrest]提供了一个matcher对象库(也称为约束或 predicate ),允许以声明方式定义“match”规则,以便在其他框架中使用。典型的场景包括测试框架、模拟库和ui验证规则。
mzsu5hc014#
您提到您对列表内容的平等性感兴趣(没有提到顺序)。所以呢
containsExactlyInAnyOrder
来自assertj的很适合。它的 Package 是spring-boot-starter-test
,例如。从assertj docs listsassert#containseactlyinyorder:
验证实际组是否完全包含给定的值,而不包含其他任何顺序的值。例子: