Bud*_*dda 13 .net extension-methods unit-testing moq mocking
扩展方法不适合测试(这里描述:使用Moq模拟扩展方法,http://www.clariusconsulting.net/blogs/kzu/archive/2009/12/22/Howtomockextensionmethods.aspx).
但是可能有一些模拟Unity方法的解决方案?在我的情况下,我有以下功能:
public class MyManager
{
public MyManager(IUnityContainer container) : base(container) { }
public IResult DoJob(IData data)
{
IMyLog log = MyContainer.Resolve<IMyLog>();
... use log.Id ...
MyContainer.Resolve<...>();//usage for other purposes...
}
Run Code Online (Sandbox Code Playgroud)
我想确定'DoJob'方法总是从容器中获取'IMyLog'对象,但不是来自其他来源......我怎么能测试它?
我最初的想法是改变'DoJob'方法的实现和使用:
IMyLog log = UnityContainer.Resolve(typeof(IMyLog)) as IMyLog;
Run Code Online (Sandbox Code Playgroud)
但'Resolve(Type t,...)'也是一种扩展方法......
欢迎任何想法.
PS请注意,"我的日志"对象是远离MyManager.DoJob创建的...
我知道我迟到了,但我遇到了同样的问题,并通过嘲笑以下方法解决了这个问题 -
IUnityContainer.Resolve(Type t, string name, params ResolverOverride[] resolverOverrides);
Run Code Online (Sandbox Code Playgroud)
例如 -
unityMock = new Mock<IUnityContainer>(MockBehavior.Strict);
validatorMock = new Mock<IValidator>(MockBehavior.Strict);
unityMock.Setup(p => p.Resolve(typeof(IValidator), null))
.Returns(validatorMock.Object);
Run Code Online (Sandbox Code Playgroud)
以防万一有人需要模拟这个并且无法删除对容器的依赖.
删除对IUnityContainer的依赖,事情变得更容易和更清洁.相反,让团结注入被抽象为接口的依赖项.这很容易被嘲笑.这是一个使用Unity的小技巧为IMyLog注入自动工厂的示例.
public class MyManager
{
private readonly Func<IMyLog> logFactory;
public MyManager(Func<IMyLog> logFactory)
{
this.logFactory = logFactory;
}
public IResult DoJob(IData data)
{
IMyLog log = logFactory();
...
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您不需要每次都创建实例:
public class MyManager
{
private readonly IMyLog myLog;
public MyManager(IMyLog myLog)
{
this.myLog = myLog;
}
public IResult DoJob(IData data)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我猜,我找到了最合适的测试解决方案:没有必要模拟统一容器并检查是否从中获取“日志”对象。我只会为“Log”对象创建一个模拟,在容器中注册其对象实例,并检查测试是否确实使用了该日志对象。
这将完成所需的操作。
Mock<IMyLog> mockLog = new Mock<IMyLog>();
mockLog.Setup(mock=>mock.Id).Returns(TestLogId);
IUnityContainer container = new UnityContainer();
container
.RegisterInstance(mockCommandExecutionLog.Object)
...
;
...
mockLog.Verify(
mock => mock.Id,
Times.Once(),
"It seems like 'Log' object is not used"
);
Run Code Online (Sandbox Code Playgroud)
谢谢。
| 归档时间: |
|
| 查看次数: |
15144 次 |
| 最近记录: |