单元测试调用另一个方法的方法

Not*_*Dan 57 testing unit-testing

对调用多个方法的方法进行单元测试的最佳方法是什么,例如:

modify(string value)
{
    if(value.Length > 5)  replaceit(value);

    else changeit(value);
}
Run Code Online (Sandbox Code Playgroud)

这个伪代码有一个修改方法(当前)调用replaceit()changeit().我已经为replaceitchangeit编写了测试,因此编写一个新的修改测试将是同一组代码的99%.我需要对它进行测试,因为它可能会在未来发生变化.

那么我是否复制粘贴现有的测试代码?将测试代码移动到一个通用功能?还有其他想法吗?我不确定这里的最佳做法.

Eri*_*son 38

这是一种经典的基于状态的测试与基于行为的测试场景.

在这个非常简单的例子测试中,输出很好.但是,在某些时候,您将遇到测试,在执行后检查状态很复杂.相反,您需要检查行为(例如,验证是否使用特定值调用changeit).

此时,您可能应该研究一个模拟对象框架,如Rhino.Mocks(.Net)或Mockito(Java),并开始编写更多基于接口的代码.


Ilj*_*euß 17

你有很多选择.哪一个最好取决于您的问题中不清楚的细节.

  • 测试modify就好像它是一个无关的方法.优势:它可能在某种程度上成为一体.
  • 只是测试你是否正确的if语句.也就是说,只要测试足以让测试强迫你编写你需要的实现(在哪里调用replaceit并且changeit只是最简单的实现可能有效.如果你正在练习TDD,这应该是你自然而然的.优点:高测试覆盖率没有很多重复的努力.
  • 子类和覆盖方法(这是"使用遗留代码有效工作"一书中的依赖性破坏技术):在仅为测试目的而引入的子类上测试方法,该子类覆盖replaceitchangeit使用固定答案或者设置感知变量(指示是否使用正确的值调用方法的变量).优点:可能会简化您的测试(或不测试),有时甚至只是使测试成为可能.
  • replaceitchangeit方法提取一个新类,包括该类的接口.测试时接口或模拟接口modify.优点:可能会使您的设计更加可测试,并且通常(或不)可以更好地解耦/重复使用.


Bil*_*ard 15

如果您已经测试replaceit()changeit()独立,那么你就留下来测试的唯一的事情是如果条件.测试modify()用几个值,以确保它调用合适的条件下,右边的功能(这些条件是nullStrings长度为4,5,6你给的例子代码).


Ian*_*oyd 6

试试吧modify.

Modify 当给定某些值时,应该返回某些值.

如何修改它的工作并不重要- 只有它能完成它的工作.

如果将来你改变modify使用不同的方法(或没有方法),它不会,也不应该,也不会影响你的测试.

那说,也测试replaceit' andchangeit`.


Gis*_*shu 5

按优先顺序排列

  1. modify(test)只有2个场景(if stmt的每个arm),所以我会写2个测试来修改表单.
    如果预期的替换结果(值)很容易确定..

.

public TestModifyIfValueLength..()
    {
      string expectedValue = .. ;// literal result of replaceit(value)
      Assert.Equals( expectedValue, modify("asd") );
    }
Run Code Online (Sandbox Code Playgroud)
  1. 如果没有,请考虑使用存根(使用子类并覆盖changeit,replaceit)来验证是否调用了正确的方法.
  2. 如果存根工作太多,那么做Mock就可以了.提取界面并设置对changeit,replacementit的期望.

假设

  • 您对replaceit(value)和changeit(value)进行了测试,全面测试这两种方法(例如所有边界条件).
  • replaceit()和changeit()是公共方法..如果没有,你应该考虑只针对公共方法编写测试.你应该可以在没有测试代码知道的情况下自由地调整/删除私有方法.