语境

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

可以从静态工厂方法创建MyObject,该方法采用的可变参数String

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

MyObject存在期间,客户可以随时通过.getComponents()方法以 List<E> 的形式检查由其创建的参数。
myObject.ofComponents(); // -> List<String>: { "Uno", "Dos", "Tres" }

换句话说,MyObject既记住并公开了使之成为现实的参数列表。有关此契约(Contract)的更多详细信息:
  • 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));
    


  • 如果我的构建路径中有库来比较这两个列表, Google Guava Iterables.elementsEqual()是最好的方法吗?我一直在为此苦恼;我应该使用遍历Iterable<E> ..检查大小然后迭代运行.equals() ..的助手方法还是Internet搜索建议的任何其他方法?比较单元测试列表的规范方法是什么?

  • 我很想获得的可选见解
  • 方法测试是否设计合理?我不是 JUnit 的专家!
  • 是将 List<E> 转换为E的可变参数的最佳方法吗?
  • 最佳答案

    我更喜欢使用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:



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

    09-04 06:22
    查看更多