如何在JUnit测试中避免多个断言?

Rav*_*avi 11 junit unit-testing

我有一个DTO,我从请求对象填充,请求对象有很多字段.我想编写一个测试来检查populateDTO()方法是否将值放在正确的位置.如果我遵循每个测试一个断言的规则,我将不得不编写大量测试来测试每个字段.另一种方法是在单个测试中编写多个断言.是否真的建议每个测试规则遵循一个断言,或者我们可以在这些情况下放松.我该如何处理这个问题?

Nil*_*esh 7

将它们分开.单元测试应该告诉你哪个单元失败了.保持它们分离还允许您快速隔离问题,而不需要您经历漫长的调试周期.


Rae*_*ald 7

是否真的建议每个单元测试只有一个断言?是的,有人提出这个建议.他们是对的吗?我不这么认为.我发现很难相信这些人实际上已经在真正的代码上工作了很长时间.

所以,imangine你有一个你想要单元测试的mutator方法.mutator有一些你要检查的效果或效果.通常,突变体的预期效果很少,因为许多效应表明突变体的设计过于复杂.每个效果有一个断言,每个断言有一个测试用例,每个mutator不需要很多测试用例,因此建议看起来并不那么糟糕.

但是这个推理的缺陷是那些测试只关注变异器的预期效果.但是如果mutator中有一个bug,它可能会产生意想不到的错误副作用.测试正在做出愚蠢的假设,即代码没有一整类错误,并且未来的重构都不会引入这样的错误.当最初编写该方法时,作者可能会明白特定的副作用是不可能的,但重构和添加新功能可能会使这种副作用成为可能.

测试长寿代码的唯一安全方法是检查mutator没有意外的副作用.但是你怎么能测试那些呢?大多数类都有一些不变量:没有变异器可以改变的东西.例如size,容器的方法永远不会返回负值.实际上,每个不变量都是每个mutator(以及构造函数)的post条件.每个突变通常还具有一组描述什么样的变化,它不变量作.例如,sort方法不会改变容器的长度.实际上,类和mutator不变量是每个 mutator调用的post条件.为所有这些添加断言是检查意外副作用的唯一方法.

那么,只需添加更多测试用例?在实践中,不变量的数量乘以要测试的变换器的数量很大,因此每次测试的一个断言导致许多测试用例.有关不变量的信息分散在许多测试用例中.调整一个不变量的设计更改将需要更改许多测试用例.这变得不切实际.最好为mutator设置参数化测试用例,使用多个断言检查mutator的几个不变量.

JUnit5的作者似乎同意.它们提供了assertAll在一个测试用例中检查多个断言的方法.


cor*_*iKa 0

该规则是否扩展到循环中?考虑一下这个

Collection expectedValues = // populate expected values
populateDTO();
for(DTO dto : myDtoContainer) 
  assert_equal(dto, expectedValues.get(someIndexRelatedToDto))
Run Code Online (Sandbox Code Playgroud)

现在我对确切的语法不太感兴趣,但这只是我正在考虑的概念。

编辑:评论后...

答案是……不!

该原理存在的原因是为了让您能够识别对象的哪些部分出现故障。如果您在一种方法中拥有它们,那么您将只会遇到一个断言,然后是下一个断言,然后是下一个断言,并且您不会看到它们全部。

因此,您可以通过以下两种方式之一获得它:

  1. 一种方法,更少的样板代码。
  2. 多种方法,更好的测试运行报告

这取决于你,两者都有好有坏。3. 列表项