【问题标题】:How to know what causes an assertEquals method to fail in unit tests?如何知道是什么导致 assertEquals 方法在单元测试中失败?
【发布时间】:2018-01-24 09:33:48
【问题描述】:

在对象或集合上使用 assertEquals() 时,我缺少 好的失败消息。失败时,错误消息会使用 toString() 方法打印出预期对象和实际对象。 它不会准确打印出导致不等式的确切原因。当然,在比较两个集合时,AssertionError 附带的消息对于找出问题所在是无用或耗时的。

以下是我不想使用的两种可能的解决方案:

  1. 可以选择编写非常具体的断言,但这样做太耗时了。
  2. 您还可以选择在您的域的 equals 方法中使用日志记录。如果 equals() 返回 false,它还会打印出导致失败的属性。我只需要查看我的控制台并在 AssertionError 之前查看打印的消息。另一方面,对于集合,使用集合的等号。例如,如果列表不相等,因为 1 个特定对象仅存在于其中一个列表中,我还希望该特定日志消息出现在控制台中。但是我不想自己编写代码

是否有框架在使用 equals 时具有这种日志记录?

是否有处理这个问题的最佳实践(或者为了避免它不需要这种日志记录)?

【问题讨论】:

  • 您的问题是您在 Collections 上调用 equals。即使它们具有相同的内容,这也会返回 false,因为集合上的 equals 是一个引用比较。如果您需要比较集合,请遍历它们并比较它们的内容
  • 我建议你对 Collections 使用 hamcrest 匹配器,如 assertThat(yourCollection, contains(item1, item2, item3)))
  • @Stultuske 这不是真的。集合的平等就很好。 ArrayList 循环遍历元素并检查对象本身的 order + 调用 equals。 Set 将通过最终调用equals来检查一个集合的所有元素是否在另一个集合中。这是关于知道为什么它返回 false。
  • @user1096301 你说得对,我想到了数组。请忽略我之前的评论。
  • @daniu 它解决了一个非常具体的案例,但只是部分解决了。它确实准确地说明了哪个对象导致了集合的不等式。但是假设该对象非常复杂并且具有很多属性,那么问题仍然是哪个属性导致了不等式。在实践中,您需要调试。或者检查 equals 失败的两个对象的 toString 输出。此外,对于数组,它不检查顺序。

标签: java unit-testing logging junit


【解决方案1】:

Spock framework 提供了这种功能。您可以使用任何表达式作为断言,它会准确打印失败的原因:

assert stack.size() == 2  // this is your assertEquals

你会得到:

Condition not satisfied:

stack.size() == 2
|     |      |
|     1      false
[push me]

我们现在在所有项目中都改用 Spock 来代替 JUnit,因为它非常方便。

【讨论】:

  • 这和你收到的信息是一样的。对于一个集合相等,它会说它不相等并显示两个集合的toString?我正在寻找可以说的内容,例如:“您的数组列表索引 5 处的元素不相等。”。或者对于两个对象相等:“对象不相等,因为属性 X 的值是 Y 并且应该是值 Z”
  • 其实你看到的更多。您会看到集合的内容,您会看到比较的值,并且会看到它们不相等的原因。对于字符串,Spock 甚至会向您显示差异,以便您可以清楚地看到它们的不同之处。它可能不是你想要的 100%,但它是对 JUnit 输出的巨大改进。为什么不试一试,看看你能不能让它为你工作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-08
  • 2021-05-08
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 2020-07-18
相关资源
最近更新 更多