在Osherove的伟大着作“单元测试的艺术”中,测试反模式之一是过度规范,这与测试对象的内部状态而不是某些预期输出基本相同。根据我的经验,使用隔离框架可能会导致与测试内部行为相同的不良副作用,因为人们往往只实现使存根与被测对象交互所必需的行为。现在,如果您的实现稍后更改(但合同保持不变),您的测试将突然中断,因为您期望存根中的某些数据未实现。
那么您认为解决这个问题的最佳方法是什么?
1)完全实现您的存根/模拟,这会产生负面的副作用,可能会使您的测试更具可读性,并且还指定了使测试通过的必要性。
2)赞成手动,完全实现的假货。
3)实现你的存根/假货,这样它们就可以让你的测试通过,然后处理这可能带来的脆弱性。
答案 0 :(得分:3)
我不认为您应该支持手动测试 - 除非您更喜欢测试而不是代码。
相反,您有另一种选择 - 如果您测试功能而不是实现,请尝试避免测试私有方法(可以重构),并且通常编写不那么脆弱的测试,您将看到使用模拟/隔离框架不要求您过度指定系统,也不会导致测试变得更脆弱。
简而言之 - 编写脆弱的测试可以在有或没有假货/模拟的情况下完成,反之亦然。
答案 1 :(得分:1)
我倾向于使用模拟而不是存根/假对象。我发现它们的麻烦要少得多,而且它们在控制测试代码方面做得更好,因为它不会被各种半生不熟的实现混乱。它们还有助于澄清正在测试的内容。
另一个优点是我只需要解决被测试的类需要模拟特定内容的地方。因此,我不必编码不重要的地方。至于验证,我只需要从被测试的类到我关心的模拟调用,并考虑测试的重要方面。
答案 2 :(得分:0)
我认为,问题总是一样的,虽然它有不同的风格:如果你的测试以某种方式覆盖了类的内部,那么你将打破覆盖这个内部代码的测试。
恕我直言,有两种方法可以解决这个问题:
我个人的'出路'是用'代码元素'来思考而不仅仅是代码。代码元素由三部分组成:文档,测试,代码。因此,如果您更改元素的一部分,您还必须调整其他两个元素 - 否则您将留下一个损坏的代码元素。