Moq IServiceProvider/IServiceScope [英] Moq IServiceProvider / IServiceScope

查看:317
本文介绍了Moq IServiceProvider/IServiceScope的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为IServiceProvider创建一个Mock(使用Moq),以便可以测试我的存储库类:

I am trying to create a Mock (using Moq) for an IServiceProvider so that I can test my repository class:

public class ApiResourceRepository : IApiResourceRepository
{
    private readonly IServiceProvider _serviceProvider;

    public ApiResourceRepository(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
        _dbSettings = dbSettings;
    }

    public async Task<ApiResource> Get(int id)
    {
        ApiResource result;

        using (var serviceScope = _serviceProvider.
            GetRequiredService<IServiceScopeFactory>().CreateScope())
        {
            var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
            result = await
                context.ApiResources
                .Include(x => x.Scopes)
                .Include(x => x.UserClaims)
                .FirstOrDefaultAsync(x => x.Id == id);
        }

        return result;
    }
}

我创建Mock对象的尝试如下:

My attempt at creating the Mock object is as follows:

Mock<IServiceProvider> serviceProvider = new Mock<IServiceProvider>();

serviceProvider.Setup(x => x.GetRequiredService<ConfigurationDbContext>())
    .Returns(new ConfigurationDbContext(Options, StoreOptions));

Mock<IServiceScope> serviceScope = new Mock<IServiceScope>();

serviceScope.Setup(x => x.ServiceProvider).Returns(serviceProvider.Object);

serviceProvider.Setup(x => x.CreateScope()).Returns(serviceScope.Object);

我收到以下错误:

System.NotSupportedException:表达式引用一个方法,该方法 不属于模拟对象:x => x.GetRequiredService()

System.NotSupportedException : Expression references a method that does not belong to the mocked object: x => x.GetRequiredService()

推荐答案

如上所述,Moq不允许设置扩展方法.

As already stated, Moq does not allow setup of extension methods.

在这种情况下,上述扩展方法的源代码可在Github上获得

In this case however the source code of the said extension methods are available on Github

ServiceProviderServiceExtensions .

解决此类问题的常用方法是找出扩展方法的作用,并在执行过程中安全地模拟路径.

The usual way around an issue like this is to find out what the extension methods do and mock a path safely through it's execution.

所有这些的基本类型是IServiceProvider及其object Getservice(Type type)方法.解决服务类型时最终会调用此方法.而且,我们只处理抽象(接口),这使得使用最小起订量变得更加容易.

The base type in all of this is the IServiceProvider and its object Getservice(Type type) method. This method is what is ultimately called when resolving the service type. And we are only dealing with abstraction (interfaces) then that makes using moq all the more easier.

//Arrange
var serviceProvider = new Mock<IServiceProvider>();
serviceProvider
    .Setup(x => x.GetService(typeof(ConfigurationDbContext)))
    .Returns(new ConfigurationDbContext(Options, StoreOptions));

var serviceScope = new Mock<IServiceScope>();
serviceScope.Setup(x => x.ServiceProvider).Returns(serviceProvider.Object);

var serviceScopeFactory = new Mock<IServiceScopeFactory>();
serviceScopeFactory
    .Setup(x => x.CreateScope())
    .Returns(serviceScope.Object);

serviceProvider
    .Setup(x => x.GetService(typeof(IServiceScopeFactory)))
    .Returns(serviceScopeFactory.Object);

var sut = new ApiResourceRepository(serviceProvider.Object);

//Act
var actual = sut.Get(myIntValue);

//Asssert
//...

查看上面的代码,您将看到该安排如何满足扩展方法的预期行为以及通过扩展(无双关)的方式来测试被测方法.

Review the code above and you would see how the arrangement satisfies the expected behavior of the extension methods and by extension (no pun intended) the method under test.

这篇关于Moq IServiceProvider/IServiceScope的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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