实例化用于测试的类

时间:2009-02-11 20:40:53

标签: testing tdd inversion-of-control

我需要测试属于服务类的方法。此服务类在构造函数中有几个依赖项,有些依赖于此方法,有些则不使用。如果我们不应该使用DI容器进行单元测试,那么实例化服务类的最佳方法是什么?

var service = new ServiceClass(new Repository1(), new Repository2(), new ServiceClass2(), etc.);

这很难阅读,看起来很多代码只是为了测试一种方法。当其中一些依赖项具有自己的依赖项时,事情变得非常混乱。

3 个答案:

答案 0 :(得分:2)

http://www.myjavatools.com/cuecards/refactoring.html

  

构造函数→工厂方法

     

如果你想要的不仅仅是简单的构造

答案 1 :(得分:2)

有时(特别是如果它是测试代码)一些代码重新格式化可以做到这一点。而

var service = new ServiceClass(new Repository1(), new Repository2(), new ServiceClass2());

绝对难以阅读,这个:

var service = new ServiceClass(
    new Repository1(), 
    new Repository2(), 
    new ServiceClass2()
);

看起来好一点(至少对我而言)。

答案 2 :(得分:2)

您应该真正考虑使用模拟框架将测试与实际的依赖对象隔离开来。我假设你使用C#(来自var关键字),所以我将举一个RhinoMock的例子。

var respository1 = MockRepository.GenerateMock<Repository1>();
repository1.Expect( r => r.SomeMethod() ).Return( someValue );

var repository2 = MockRepository.GenerateMock<Repository2>();
repository2.Expect( r => r.Method2() ).Return( someValue );

 ...

var service = new Service( repository1, repository2, ... );

repository1.VerifyAllExpectations();
repository2.VerifyAllExpectations();

使用此机制,您可以控制模拟对象如何响应正在测试的类,并将测试代码与相关依赖项隔离开来。您还可以通过验证您设置的期望是否已满足(称为)来测试您所测试的类是否正确地与它所依赖的类进行交互。

对于构造函数中的参数数量,请考虑提供一个默认构造函数,该构造函数不接受任何参数并具有依赖项的公共setator。然后,您可以使用C#3.0中的便捷机制来定义它们。

var service = new Service {
    Repository1 = repository1,
    Repository2 = repository2,
    ...
};