我正在尝试学习单元测试,但会导致设计问题。考虑类 A 依赖于类 B。如果要为 B 创建存根以便对 A 进行单元测试,大多数隔离框架要求 B 必须是接口,或者 A 使用的所有方法都必须是虚拟的。B 本质上不能是具有非虚拟方法的具体类,以便进行单元测试。
这对生产代码的设计施加了重大限制。如果我必须为每个依赖项创建一个接口,那么类的数量将增加一倍。遵循单一职责原则会导致小类相互依赖,因此这会增加接口的数量。我还为易失性依赖项(将来可能会更改)或设计需要它以实现可扩展性创建接口。仅仅为了测试而使用接口污染生产代码将显着增加其复杂性。使所有方法都虚拟化似乎也不是一个好的解决方案。它给继承者的印象是这些方法可以被覆盖,即使它们不是,实际上这只是单元测试的副作用。
这是否意味着可测试的面向对象设计不允许具体的依赖关系,或者是否意味着不应该伪造具体的依赖关系?“必须伪造每个依赖项(存根或模拟)才能正确进行单元测试”是我到目前为止所学到的,所以我不认为后者是这种情况。JustMock 和 Isolator 之外的隔离框架不允许在没有虚拟方法的情况下伪造具体的依赖关系,有些人认为 JustMock 和 Isolator 的强大功能会导致糟糕的设计。我认为模拟任何类的能力非常强大,如果你知道自己在做什么,它将保持生产代码的设计干净。