首页 > 其他分享 >.NET 8 Moq mock GetRequiredKeyedService Setup报错yk

.NET 8 Moq mock GetRequiredKeyedService Setup报错yk

时间:2024-08-30 19:04:49浏览次数:11  
标签:yk service Setup object --- GetRequiredKeyedService 报错 type

.NET 8 Moq mock GetRequiredKeyedService Setup报错

项目代码里有地方用到IServiceProvider.GetRequiredKeyedService来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:



|  | var serviceProvider = new Mock<IServiceProvider>(); |
| --- | --- |
|  | serviceProvider.Setup(x => x.GetRequiredKeyedService<AAA>(It.IsAny<BBB>())).Returns(new CCC()); |


没想到报错了:



|  | Test method threw exception: |
| --- | --- |
|  | System.NotSupportedException: Unsupported expression: x => x.GetRequiredKeyedService(It.IsAny<Type>(), It.IsAny()) |
|  | Extension methods (here: ServiceProviderKeyedServiceExtensions.GetRequiredKeyedService) may not be used in setup / verification expressions. |
|  |  |
|  | Stack Trace: |
|  | Guard.IsOverridable(MethodInfo method, Expression expression) line 87 |
|  | MethodExpectation.ctor(LambdaExpression expression, MethodInfo method, IReadOnlyList`1 arguments, Boolean exactGenericTypeArguments, Boolean skipMatcherInitialization, Boolean allowNonOverridable) line 236 |
|  | ExpressionExtensions.g__Split|5_0(Expression e, Expression& r, MethodExpectation& p, Boolean assignment, Boolean allowNonOverridableLastProperty) line 256 |
|  | ExpressionExtensions.Split(LambdaExpression expression, Boolean allowNonOverridableLastProperty) line 170 |
|  | Mock.SetupRecursive[TSetup](Mock mock, LambdaExpression expression, Func`4 setupLast, Boolean allowNonOverridableLastProperty) line 728 |
|  | Mock.Setup(Mock mock, LambdaExpression expression, Condition condition) line 562 |
|  | Mock`1.Setup[TResult](Expression`1 expression) line 645 |


有点奇怪,难道GetRequiredKeyedService不是接口方法?查看.NET源代码,果然,GetRequiredKeyedService是IServiceProvider的扩展方法,而我们知道Moq是不支持Setup扩展方法的。



|  | /// |
| --- | --- |
|  | /// Get service of type  from the . |
|  | /// |
|  | /// The type of service object to get. |
|  | /// The  to retrieve the service object from. |
|  | /// An object that specifies the key of service object to get. |
|  | /// A service object of type . |
|  | /// There is no service of type . |
|  | public static T GetRequiredKeyedService<T>(this IServiceProvider provider, object? serviceKey) where T : notnull |
|  | { |
|  | ThrowHelper.ThrowIfNull(provider); |
|  |  |
|  | return (T)provider.GetRequiredKeyedService(typeof(T), serviceKey); |
|  | } |
|  |  |


原因找到就好办了,翻看源码,一步步找到IServiceProvider.GetRequiredKeyedService最终调用的接口方法,然后再mock即可。

首先看下requiredServiceSupportingProvider.GetRequiredKeyedService(serviceType, serviceKey)调的是什么方法



|  | /// |
| --- | --- |
|  | /// IKeyedServiceProvider is a service provider that can be used to retrieve services using a key in addition |
|  | /// to a type. |
|  | /// |
|  | public interface IKeyedServiceProvider : IServiceProvider |
|  | { |
|  | /// |
|  | /// Gets the service object of the specified type. |
|  | /// |
|  | /// An object that specifies the type of service object to get. |
|  | /// An object that specifies the key of service object to get. |
|  | ///  A service object of type serviceType. -or- null if there is no service object of type serviceType. |
|  | object? GetKeyedService(Type serviceType, object? serviceKey); |
|  |  |
|  | /// |
|  | /// Gets service of type  from the  implementing |
|  | /// this interface. |
|  | /// |
|  | /// An object that specifies the type of service object to get. |
|  | /// The  of the service. |
|  | /// A service object of type . |
|  | /// Throws an exception if the  cannot create the object. |
|  | object GetRequiredKeyedService(Type serviceType, object? serviceKey); |
|  | } |
|  |  |


可以看到IKeyedServiceProvider也是继承了IServiceProvider接口,这就更好办了,我们直接Mock IKeyedServiceProvider再Setup即可,将用到IServiceProvider的地方,换成IKeyedServiceProvider。

代码如下:



|  | var serviceProvider = new Mock<IKeyedServiceProvider>(); |
| --- | --- |
|  | serviceProvider.Setup(x => x.GetRequiredKeyedService(It.IsAny<AAA>(), It.IsAny<BBB>())).Returns(new CCC()); |


运行测试,完美。

总结

解决这个问题并不困难,但是如果.Net不开源,看不到源代码,还是有点头疼。

本博客参考飞数机场。转载请注明出处!

标签:yk,service,Setup,object,---,GetRequiredKeyedService,报错,type
From: https://www.cnblogs.com/westworldss/p/18389359

相关文章

  • .NET 8 Moq mock GetRequiredKeyedService Setup报错Hz
    .NET8MoqmockGetRequiredKeyedServiceSetup报错项目代码里有地方用到IServiceProvider.GetRequiredKeyedService来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:||varserviceProvider=newMock<IServiceProvider>();||---|---|||serviceP......
  • g++链接报错:undefined reference to typeinfo of xxx
    g++链接报错:undefinedreferencetotypeinfoofxxx问题背景在项目中遇到了这样一个问题:C++文件编译都OK,但链接的时候报错:undefinedreferencetotypeinfoforxxx。std::typeinfo是C++中的RTTI(RunTimeTypeIdentification)机制中记录类型信息用的,dynamic_cast和typeid......
  • ModuleNotFoundError: No module named ‘utils.query‘ flask项目遇到这种报错怎么解
    ModuleNotFoundError:Nomodulenamed'utils.query'这个错误表明你的Python代码正在尝试导入一个名为utils.query的模块,但未能成功找到它。以下是解决该问题的几个步骤:1.检查模块路径如果utils.query是你自己的模块或在项目中的某个目录下,确保文件路径正确。util......
  • openGauss报错:Too many open files,解决方案
    操作系统信息Linuxuser-pc5.4.18-87.76-generic#gfb16-KYLINOSSMPThuAug3109:05:44UTC2023aarch64aarch64aarch64GNU/Linux解决方案当前使用gsql-dpostgres-p5432-r命令登录数据的时候,报错如下:gsql:FATAL:couldnotlookuplocaluserID1002:......
  • .NET 8 Moq mock GetRequiredKeyedService Setup报错b9
    .NET8MoqmockGetRequiredKeyedServiceSetup报错项目代码里有地方用到IServiceProvider.GetRequiredKeyedService来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:||varserviceProvider=newMock<IServiceProvider>();||---|---|||serviceP......
  • vs2022引用了dll,本地启动调试的时候报错
     问题描述:引用了公司类库之后,使用vs2012以及vs2015进行编译调试都没有问题,放站点下也正常运行;但是用vs2022编译之后,启动调试报错,但是放站点上正常运行;报错:“检索COM类工厂中CLSID为{33DBD6AC-03F5-4CCD-9711-FFBA69267E41}的组件失败,原因是出现以下错误:80040154没......
  • 使用Opatch命令报错:Java (1.7) could not be located. OPatch cannot proceed!
    问题描述[oracle@servernamedb]$OPatch/opatchversionOPatch/opatch:line839:[:toomanyargumentsOPatch/opatch:line839:[:toomanyargumentsJava(1.7)couldnotbelocated.OPatchcannotproceed!OPatchreturnswitherrorcode=1解决方案删除OPatch目录......
  • .NET 8 Moq mock GetRequiredKeyedService Setup报错
    .NET8MoqmockGetRequiredKeyedServiceSetup报错项目代码里有地方用到IServiceProvider.GetRequiredKeyedService<T>来解析服务,在写单元测试时需要Mock它,本以为像下面这样写就可以了:varserviceProvider=newMock<IServiceProvider>();serviceProvider.Setup(x=>x.GetR......
  • Spring security的SecurityConfig配置时 userDetailsService报错如何解决?
    文章目录报错信息原因解决方案1.实现`UserDetailsService`接口修改`IUsersService`接口和实现类2.修改`SecurityConfig`3.其他注意事项报错信息‘userDetailsService(T)’in‘org.springframework.security.config.annotation.authentication.builders......
  • Vue的那些报错
    【Vue-cli】npminstall时报错:npmERRCouldnotresolvedependencynpmERRpeernpmERR!codeERESOLVEnpmERR!ERESOLVEunabletoresolvedependencytreenpmERR!npmERR!Whileresolving:[email protected]!Found:[email protected]!node_modules/es......