如何用Moq模拟Autofaq接口 [英] How to mock Autofaq interface with Moq

查看:84
本文介绍了如何用Moq模拟Autofaq接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆