【发布时间】:2012-03-20 05:37:22
【问题描述】:
我正在对使用统一依赖注入框架的类进行单元测试。
这将返回 null: ServiceLocator.Current.GetInstance();
我怎样才能让它返回一个模拟对象或只返回对象本身?
【问题讨论】:
标签: unit-testing unity-container
我正在对使用统一依赖注入框架的类进行单元测试。
这将返回 null: ServiceLocator.Current.GetInstance();
我怎样才能让它返回一个模拟对象或只返回对象本身?
【问题讨论】:
标签: unit-testing unity-container
你可以使用穷人的注射剂。创建一个默认构造函数,该构造函数从服务定位器中检索依赖项,并将这些依赖项转发给将它们作为参数的“真实”构造函数。这可以处理生产情况。
然后在测试相关类时,将依赖项的假/模拟版本传递给“真实”构造函数,完全绕过默认构造函数。
【讨论】:
MSDN 有这个例子显示how to implement the service locator pattern with Unity。本质上,您应该将服务定位器对象作为类的构造函数参数传递。这使您能够通过MockUnityResolver,从而使您能够完全控制单元测试。
[TestMethod]
public void InitCallsRunOnNewsController()
{
MockUnityResolver container = new MockUnityResolver();
var controller = new MockNewsController();
container.Bag.Add(typeof(INewsController), controller);
var newsModule = new NewsModule(container);
newsModule.Initialize();
Assert.IsTrue(controller.RunCalled);
}
【讨论】:
您是否正在测试您的核心“DI 集成”代码?如果没有,您的普通代码不应该(嗯,很少)与您的 DI 框架进行交互。
通常,您的依赖项将通过构造函数注入注入,并且在测试时,您可以提供模拟对象作为这些构造函数依赖项。例如:
public class Foo {
public Foo (IBar bar) {
bar.Lift ();
}
}
使用上面的代码,您可以简单地模拟 IBar,并将其传递给 Foo 构造函数。
【讨论】:
您始终可以设置 Container+ServiceLocator 并实际满足所需的依赖关系,例如,通过注册模拟。有关如何设置容器/定位器的信息,请参见代码示例 #4:
http://blogs.msdn.com/b/miah/archive/2009/05/12/servicelocator-and-unity-be-careful.aspx
【讨论】: