使用 C#/Autofac/Moq:我有这样的课程:
public class MyService
{
private readonly IlifetimeScope _scope;
public MyService(ILifetimeScope scope)
{
_scope = scope;
}
public void DoWork()
{
var dbContext = _scope.Resolve<IDataContext>();
}
}
这在运行时起作用。但是,我无法对其进行单元测试,因为我无法模拟 Resolve() 方法。它是一种扩展方法。
能够嘲笑它的最好方法是什么?显而易见的事情是在构造函数中注入 IDataContext 而不是 ILifetimeScope,但由于各种原因我不能。
那么,注入 Func 会起作用吗?
public class MyService
{
private readonly Func<IDataContext> _dbContext;
public MyService(Func<IDataContext> dbContext)
{
_dbContext = dbContext;
}
public void DoWork()
{
var ctxt = _dbContext();
// do stuff
}
}
如:我可以模拟它,但是 Autofac 会弄清楚如何将正确的参数注入到 ctor 中吗?或者有更好/更简单的方法来做到这一点?
我知道这样做并不理想,但在一些更不常见的情况下可能有必要。
我的情况有点不同。我有一个需要按需创建新上下文的方法,它是一个控制台应用程序,因此它不像核心的 MVC 那样会根据请求开始一个新的生命周期范围。所以我得到了 Autofac/Moq 扩展:http://autofac.readthedocs.io/en/latest/integration/moq.html http://autofac.readthedocs.io/en/latest/integration/moq.html
这将允许您告诉容器为特定接口返回什么实例。
然后你几乎可以这样做:
[Fact]
public void Test()
{
using (var mock = AutoMock.GetLoose())
{
var moqMockMe = new Mock<MockMe>();
moqMockMe.Setup(s => s.AmIMocked()).Returns("Yes");
mock.Provide(moqMockMe.Object);
var lifeTimeScope = mock.Create<ILifetimeScope>();
using (var scope = lifeTimeScope.BeginLifetimeScope())
{
var mockMeInsideScope = scope.Resolve<MockMe>();
var actual = mockMeInsideScope.AmIMocked();
Assert.Equal("Yes", actual);
}
}
}
public interface MockMe
{
string AmIMocked();
}
public class MockMeImpl : MockMe
{
public string AmIMocked()
{
return "No";
}
}
因此,如果您调用的服务有一个开始新的生命周期作用域的方法,您可以模拟结果并使用上面示例中创建的假 ILifeTimeScope 来测试它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)