MSTest TestMethod依赖注入

时间:2010-11-24 16:34:49

标签: .net visual-studio-2010 dependency-injection mstest

我正在使用DI容器,我想通过容器中解析的实例进行MSTest(VS 2010)单元测试。

我想将这些实例注入我的TestMethod或至少我的TestClass。这可能吗?

现在我的TestMethods直接调用container.Resolve<T>(xxx),我宁愿避免这样做,以便我的注射测试更加真实。

任何人都有这方面的经验吗?

提前致谢。

2 个答案:

答案 0 :(得分:6)

测试类的实例化深入地发生在MSTest框架的内部类中,因此将依赖项注入其中将是一项具有挑战性的任务。

答案 1 :(得分:5)

根据依赖注入模式编写代码并使用IoC框架的主要原因是获得可测试的代码。但是,在测试代码中使用IoC容器会得到相反的结果。根据您的问题,我可以看到您已经体验过这一点。

使用服务定位器(SL)模式而不是依赖注入(DI)模式时尤其如此。使用SL模式,类直接调用IoC容器(或此类容器的抽象),而不是为类提供所需的依赖项(使用构造函数注入)。由于类直接调用容器,因此您还需要在测试环境中配置该容器。这很痛苦,因为测试配置或假对象通常变得非常复杂,因为您经常希望在每个测试的基础上影​​响假的行为,同时保持线程安全,因为测试框架可能并行运行您的测试( MSTest这样做)。我知道我在过去写过一些疯狂的线程安全测试代码,然后才发现我做错了: - (。

因此,您应该在应用程序代码中使用DI模式,并且在测试中,您应该手动连接这些依赖项。例如,在对依赖于HomeController类的ICustomerService类进行测试时,通常应在测试类中使用CreateController()CreateValidController工厂方法来集中创建HomeController。这样可以避免在每次测试中编写这些依赖项,从而在测试代码中创建维护噩梦。在这个工厂方法中,您可以通过以下操作手动注入FakeCustomerService类:

private static HomeController CreateController(
    InMemoryDataMapper mapper)
{
    var uowFactory = new FakeNorthwindUnitOfWorkFactory()
    {
        UnitOfWork = new NorthwindUnitOfWork(mapper);
    };

    return new HomeController(new FakeCustomerService(uowFactory));
}

这样的工厂方法看起来当然取决于HomeController的依赖结构看起来如何(没有双关语)。

简而言之,不要尝试在测试代码中执行依赖注入,就像在应用程序代码中一样。测试框架不仅难以实现这一点,而且还意味着您必须为测试环境配置IoC框架,在这种情况下,您将面临失败。不幸的是,我从经验谈起。