dpa*_*ons 0 c# unit-testing dependency-injection rhino-mocks unity-container
我有一个使用Unity for DI的应用程序但我在编写单元测试时遇到了一些麻烦.在我的一些业务层方法中,我有与此类似的代码:
var obj = container.Resolve<ISomeObj>();
Run Code Online (Sandbox Code Playgroud)
这要么是站在一个最终会传递给数据库的内存中对象,要么是最终传递给客户端的内存中对象.但问题是RhinoMocks(貌似)无法正确地模拟容器,所以做这样的事情:
mockContainer = MockRepository.GenerateMock<IUnityContainer>();
mockContainer.Expect(x => x.Resolve<ISomeObj>())
.Return(mockObj);
Run Code Online (Sandbox Code Playgroud)
在这里获得异常似乎是有道理的,因为容器实际上是空的,但我没有看到解决问题的直接方法.我曾考虑用包装器抽出容器以解决这个问题,但这似乎有点矫枉过正.
任何想法或建议都非常感谢!
- - 编辑 - -
由于Yacoub发布了他的答案,我一直在阅读有关服务定位器(反)模式的一些内容,虽然人们普遍认为这是一种反模式,但我还没有找到关于如何处理POCO的答案.
使用上面的例子,似乎我的问题的一般答案是做这样的事情:
public class Foo()
{
private ISomeObj someObj;
public Foo(ISomeObj injectObj)
{
someObj = injectObj;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为我对此方法的唯一抱怨是它(可能)使构造函数"忙"ala:
public class Foo()
{
public Foo(ISomeService injectSvc, ISomeObj injectObj, ISomeObj2 injectObj2, ISomeObj3 injectObj3)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
此外,除非我遗漏了某些内容,否则我需要一种方法来重新初始化给定的实例以供重用.含义:如果MethodA()和MethodB()都使用了ISomeObj,当MethodA()完成ISomeObj时,我需要重新初始化ISomeObj中的所有字段,以便MethodB()可以完成它的工作.
解决这个问题的"最佳"方法是什么?
您正在做什么(使用业务层方法内部的容器解析对象)称为服务位置,并被视为反模式.您可能需要考虑重构以使用构造函数注入.如果你这样做,那么你就不需要在单元测试中使用容器了.
话虽如此,如果没有这样的重构,你可以做到这一点:不要嘲笑容器.相反,使用一个真正的容器,并使用容器注册模拟实例,如下所示:
container.RegisterInstance<ISomeObj>(mockObj); //mockObj is the mocking object that implements ISomeObj
Run Code Online (Sandbox Code Playgroud)
为此interface(ISomeObj)完成的所有解析操作都将返回相同的实例.
如果您需要能够为每个解析操作获取新实例,则可以执行以下操作:
container.RegisterType<ISomeObj>(new InjectionFactory(x => GenerateMock()));
Run Code Online (Sandbox Code Playgroud)
GenerateMock创建模拟对象的方法在哪里.您可以使用RhinoMocks创建模拟的代码替换此调用.
| 归档时间: |
|
| 查看次数: |
930 次 |
| 最近记录: |