gpt4 book ai didi

c# - 调用扩展方法时如何使用 Moq 模拟 Autofaq 接口(interface)

转载 作者:太空宇宙 更新时间:2023-11-03 16:59:51 24 4
gpt4 key购买 nike

使用 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() 方法。它是一种扩展方法。

模拟它的最佳方法是什么?显而易见的事情是在构造函数中注入(inject) IDataContext 而不是 ILifetimeScope,但出于各种原因我不能。

那么,注入(inject) 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 会弄清楚如何将正确的参数注入(inject) ctor 吗?还是有更好/更简单的方法来做到这一点?

最佳答案

我知道这样做并不理想,但在一些更不常见的情况下,这可能是必要的。

我的情况有点不同。我有一个方法需要根据需要创建一个新的上下文,它是一个控制台应用程序,所以它不像核心的 MVC,它会根据请求开始一个新的生命周期。所以我得到了 Autofac/Moq 扩展:http://autofac.readthedocs.io/en/latest/integration/moq.html

这将允许您告诉容器为特定接口(interface)返回什么实例。

那么你几乎可以这样做:

[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 来测试它。

关于c# - 调用扩展方法时如何使用 Moq 模拟 Autofaq 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44143810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com