使用虚拟保护工厂方法来模拟在类中创建的对象?

时间:2016-05-12 10:01:15

标签: c# unit-testing mocking mstest rhino-mocks

Rhino Mocks与使用依赖注入和构造函数注入的设计模式紧密结合,但我通常不遵循依赖注入范例,并且不喜欢仅为我的测试工具重新构建我的解决方案。 / p>

采取这种情况:

class MyClass{
    public void MyMethod(...){
      var x = new Something(...);
      x.A();
      x.B();
      x.C();
    }
}

相反,执行以下操作是非常典型和可接受的,因为这不是我通常希望注入依赖项的情况 - 它可以被视为MyClass'行为/逻辑的一部分。

class MyClass{
    public void MyMethod(...){
      var x = NewSomething(...);
      x.A();
      x.B();
      x.C();
    }
    virtual protected Something NewSomething(...){
      return new Something(...);
    }
}

现在我可以(我认为)扩展MyClass作为我的测试项目中的具体类,或者使用Rhino ......对吗?这是a)正确的b)一种合理合理,常见的做事方式吗?

我可以看到除DI之外的另一种方法可能是我的项目中实际上有一个ClassFactory类,它根据需要创建所有实例;然后我找到了一种在我的测试中模拟/存根的方法。但这对我来说似乎很“臭”,虽然我知道这是一种人们使用的模式。

2 个答案:

答案 0 :(得分:1)

在尝试使遗留代码更易于测试时,我已经使用了很多次,尽管它真的很想回来再咬你。

基本上,模拟/伪造/测试是你的敌人。你应该讨厌它们并避免它们(编辑说明:我不是说不要使用它们,我只是说你必须使用它们)。这一切都遵循范式,即所有代码都是错误的代码,我们应该根据需要编写尽可能少的代码来完成任务。拥有一堆覆盖虚拟方法的测试双打会使您的代码非常严格。即使您的生产代码仅在一个地方调用该方法,更改方法签名也会非常痛苦,因为您的测试双精度也会中断。这也让以后清理混乱并实际注入依赖性变得很痛苦(是的,我认为注入的东西是客观上更好的(tm))。

它归结为基本上:是的,这样做会使您的代码更易于测试,但没有任何通常通过测试获得的好处。你没有更好的设计,你会有严格的代码等。

我不会指出任何一个手指,因为我喜欢我曾说过有时只是为了测试一下是否有效。它可以是一个“足够好”的临时解决方案,但我的最终答案是“如果你完全可以避免它(并且仍然有测试代码)可能不会”。

答案 1 :(得分:0)

你会用你建议的方法牺牲单一责任模式(SRP),并且可以说你的代码更难以阅读,理解和维护,在我们讨论测试之前就有一种气味。

如果您计划运行测试,同时不遵循SOLID principles,那么您在哪里节省时间,可读性或灵活性? (老实说,我很想知道)。

DI原则允许您执行的操作是完全独立于依赖项运行测试,这正是您想要做的事情。

OOP的SOLID原则为他们提供了许多好的论据,但我总是乐于学习和错误,但我必须说,我可能被几年的SOLID代码所蒙蔽,成千上万的绿色单元测试保护我的项目。