我正在使用DI容器,我想通过容器中解析的实例进行MSTest(VS 2010)单元测试。
我想将这些实例注入我的TestMethod或至少我的TestClass。这可能吗?
现在我的TestMethods直接调用container.Resolve<T>(xxx)
,我宁愿避免这样做,以便我的注射测试更加真实。
任何人都有这方面的经验吗?
提前致谢。
答案 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框架,在这种情况下,您将面临失败。不幸的是,我从经验谈起。