一尘不染

如何用JUnit测试那两个列表 包含相同顺序的相同元素?

java

语境

我正在为该类编写一个简单的 JUnit
测试MyObject

MyObject可以从静态工厂方法,需要一个可变参数的创建
字符串

MyObject.ofComponents("Uno", "Dos", "Tres");

在的存在期间的任何时间MyObject,客户端可以检查它通过在的形式创建的参数 列表
,通过.getComponents()方法。

myObject.ofComponents(); // -> List<String>: { "Uno", "Dos", "Tres" }

换句话说,a MyObject既记住并公开了使之成为现实的参数列表。有关此合同的更多详细信息:

  • 的顺序getComponents将与为对象创建选择的顺序相同
  • 允许重复的后续 String 组件并按顺序保留
  • 行为null未定义(其他代码保证没有null出厂)
  • 对象实例化后,无法更改组件列表

我正在编写一个简单的测试,该测试MyObject
String 列表创建一个,并检查它是否可以通过返回相同的列表.getComponents()
我立即执行此操作,但这应该在现实的代码路径中一定距离处发生

这是我的尝试:


List<String> argumentComponents = Lists.newArrayList("One", "Two", "Three");
List<String> returnedComponents =
    MyObject.ofComponents(
        argumentComponents.toArray(new String[argumentComponents.size()]))
        .getComponents();
assertTrue(Iterables.elementsEqual(argumentComponents, returnedComponents));

  • 谷歌番石榴 Iterables.elementsEqual()最好的办法,只要我有库在我的构建路径,那些两个列表比较? 我一直在为此苦恼; 我应该使用遍及Iterable ..检查大小然后迭代运行的.equals()..或Internet搜索建议的任何其他方法的帮助器方法吗?比较单元测试列表的规范方法是什么?

我希望获得的可选见解

  • 方法测试是否设计合理?我不是 JUnit 专家!
  • .toArray()List 转换为 E 的可变参数的最佳方法是吗?

阅读 208

收藏
2020-12-03

共1个答案

一尘不染

我更喜欢使用Hamcrest,因为如果出现故障,它可以提供更好的输出

Assert.assertThat(listUnderTest, 
       IsIterableContainingInOrder.contains(expectedList.toArray()));

而不是报告

expected true, got false

它会报告

expected List containing "1, 2, 3, ..." got list containing "4, 6, 2, ..."

IsIterableContainingInOrder.contain

Hamcrest

根据Javadoc:

为Iterables创建一个匹配器,当在经过检查的Iterable上单次通过时,该匹配器将产生一系列项目,每个项目在逻辑上均等于指定项目中的相应项目。对于正匹配,所检查的可迭代项的长度必须与指定项目的数量相同

因此,listUnderTest必须具有相同数量的元素,并且每个元素必须按顺序匹配期望值。

2020-12-03