2009-05-04 125 views
6

我试图学习依赖注入,并遇到单元测试应用程序时出现问题。依赖注入解决方案和单元测试

我正在写一个控制台应用程序,创建并在main()初始化的容器,它可作为一个Program.Containerget-property,在我的应用程序,以便在任何地方我可以打电话Program.Container.Resolve<..>()

我有一个ServiceValidator类是这样的:

public class ServiceValidator 
{ 
    private readonly IConfiguration _configuration; 
    private readonly IService _service; 

    public ServiceValidator(IConfiguration configuration, IService service) 
    { 
     _configuration = configuration; 
     _service = service; 
    } 

在另一大类我用

ServiceValidator serviceValidator = Program.Container.Resolve<ServiceValidator>(); 
serviceValidator.VerifyVersion(); 

这引起了我的问题,在单元测试Program.Container.Resolve通话,因为它不已设置。

那是一个不好的做法,呼吁解决在容器上?我可以在Main()中创建ServiceValidator实例并传递该对象,但这似乎很愚蠢,因为它会导致只传递给下一个方法的对象的很多参数。

所以我想这是可以接受的一类中调用化解,但随后的容器必须配置为单元测试。我应该怎么做,我应该把容器移到另一个地方而不是Program课程吗?你会推荐什么?

如果它的事项,我使用的是团结和C#

感谢:-)

回答

8

这是一个不好的做法,在容器上调用解析?我可以在Main()中创建ServiceValidator实例并传递该对象,但这似乎很愚蠢,因为它会导致只传递给下一个方法的对象的很多参数。

当您一路使用依赖注入时,则不需要将大量参数传递给对象。每个对象的构造函数应该只有它自己直接使用的那些依赖关系的参数 - 它不会知道它的直接依赖关系的传递依赖关系。

因此,如果您有一个需要ServiceValidator的类X,那么类X将具有ServiceValidator类型的构造函数参数。那么如果某个类Y使用类X,那么类Y将具有类型X的构造函数参数。请注意,Y 对ServiceValidator没有任何知识,因此您不需要将ServiceValidator从一个类传递到另一个类 - 唯一的地方在构建X时使用它,这通常是由DI框架完成的,或者在手写体工厂中只有一个地方完成。

更多信息,有些链接:

1

我通常允许呼叫解决从容器依赖于像主要场所,虽然我还是尽量保持对它们一最小。然后我做的是在测试类的初始化方法中配置容器。我已经用任何需要调用容器的测试类对它进行初始化。

这不叫什么需要初始化容器测试类就能够忽略它,而不是使用假货。我通常在这些情况下使用mock。

我也用Microsoft Service Locator,这样,我走的是依赖是从.NET框架,而不是在特定容器的东西。这使我可以在路上使用任何我想要的东西,即使是家庭酿造的容器。

+0

我还是想看看如何解决这个问题一个很好的模式,而又不使程序类... – 2009-05-04 13:38:33

+0

的依赖>我存话费这样的.. 你的意思是“决心”调用容器? – Karsten 2009-05-04 13:40:59

+0

是的,我的意思是'解决'呼叫集装箱。 – 2009-05-04 14:44:05

0

你可以使用一个静态类作为您的容器的初始化。像BootStrapper.cs会很好。然后您可以在代码和测试中引用类方法。

0

那么你正在做的技术是在你的类服务的位置。

我记得读这篇文章而回:

http://martinfowler.com/articles/injection.html

对于我的课我从来没有试图在他们使用的决心。当我需要它们时,我通过容器创建对象。对于单元测试,我要么使用一些模拟库和存根类。

0

的问题在于事实上你正试图测试Main方法。这种方法几乎不可能进行单元测试。

我认为最好不要进行单元测试你的主要方法,因为:

  • 现代单元测试的重点是关于设计
  • 你应该尽量减少在单元测试中对配置的依赖。配置可以通过烟雾或集成测试进行测试。