如何用Moq模拟Autofaq接口 [英] How to mock Autofaq interface with Moq
问题描述
使用C#/Autofac/Moq:我有这个课程:
Using C#/Autofac/Moq: I have this class:
public class MyService
{
private readonly IlifetimeScope _scope;
public MyService(ILifetimeScope scope)
{
_scope = scope;
}
public void DoWork()
{
var dbContext = _scope.Resolve<IDataContext>();
}
}
这在运行时有效.但是,由于无法模拟Resolve()方法,因此无法对其进行单元测试.这是一种扩展方法.
This works at runtime. However, I can't unit test it, since I cannot mock the Resolve() method. It is an extension method.
能够模拟它的最佳方法是什么?显而易见的事情是将IDataContext而不是ILifetimeScope注入构造函数中,但是由于种种原因,我无法这样做.
What's the best way to be able to mock it? The obvious thing would be to inject the IDataContext in the constructor instead of the ILifetimeScope, but for various reasons I cannot.
那么,注入一个Func会起作用吗?
So, would it work to inject a Func instead?
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注入正确的参数吗?还是有更好/更简单的方法来做到这一点?
As in: I can mock it, but will Autofac figure out how to inject the correct parameter to the ctor? Or is there a better/simpler way to do this?
推荐答案
我知道这样做不是很理想,但是在一些较不常见的情况下,可能有必要.
I know doing this is not ideal, but in some more uncommon scenarios it may be necessary.
我的处境略有不同.我有一个需要按需创建新上下文的方法,它是一个控制台应用程序,因此它不像core的MVC会为每个请求启动一个新的lifescope.因此,我得到了Autofac/Moq扩展名: http://autofac.readthedocs.io /en/latest/integration/moq.html
I had a situation that was a bit different. I have a method that needs to create a new context on demand, it is a console app so it's not like core's MVC that would begin a new lifetimescope per request. So I got the Autofac/Moq extension: http://autofac.readthedocs.io/en/latest/integration/moq.html
这将允许您告诉容器针对特定接口返回哪个实例.
This will allow you to tell the container what instance to return for a particular interface.
然后您几乎可以这样做:
Then you can pretty much do it like this:
[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";
}
}
因此,如果您正在调用的服务具有开始新的Lifescope的方法,则可以使用上面示例中创建的该假ILifeTimeScope来模拟结果并对其进行测试.
So in case the service you're calling has a method that begins a new lifetimescope, you can mock the result and test it by using this fake ILifeTimeScope created in the example above.
这篇关于如何用Moq模拟Autofaq接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!