使用dotnet CLI运行单元测试遇IOptions泛型类型继承访问错误
解决dotnet CLI运行单元测试时JustMock无法处理internal泛型参数的问题
问题场景
使用dotnet CLI + xUnit + JustMock组合运行单元测试时抛出异常:
Abstract type Microsoft.Extensions.Options.IOptions'1[Models.DevOpsOptions] is not accessible for inheritance
相关配置与代码
- UserManagement项目中的internal类:
internal class DevOpsOptions { public string Username { get; set; } public string Password { get; set; } }
- 已配置InternalsVisibleTo:
在UserManagement项目的csproj中添加测试项目的访问权限:
<ItemGroup> <InternalsVisibleTo Include="$(AssemblyName).Tests" /> </ItemGroup>
- 测试用例:
右键在IDE中运行测试完全正常,但执行dotnet test .\UserManagement.Test.csproj时触发异常,测试代码关键片段:
[Fact] public async void ThrowArgumentException_WhenUserEmailIsNull() { // Arrange HttpClient httpClient = Mock.Create<HttpClient>(); ClientOptions clientApplicationOptions = Mock.Create<ClientOptions>(); IOptions<DevOpsOptions> devOpsOptions = Mock.Create<IOptions<DevOpsOptions>>(); AzureDevOpsSettings azureDevOpsSettings = new AzureDevOpsSettings(); IHttpDevOpsServiceClient httpDevOpsServiceClient = new HttpDevOpsServiceClient(httpClient, clientApplicationOptions, devOpsOptions); // Act async Task actAsync() => await httpDevOpsServiceClient.DeleteUser(null, azureDevOpsSettings); // Assert await Assert.ThrowsAsync<ArgumentException>(actAsync); }
原因分析
JustMock创建接口mock时,会动态生成继承目标接口的代理类。这里目标接口是IOptions<DevOpsOptions>,泛型参数DevOpsOptions是internal类型。虽然InternalsVisibleTo让测试项目能访问该internal类型,但dotnet CLI运行测试时,动态生成的代理程序集并没有被授予访问DevOpsOptions的权限,导致无法创建合法的代理类型,最终抛出异常。而IDE运行时的权限上下文与CLI不同,所以能正常执行。
解决方法
将DevOpsOptions的访问修饰符改为public,这样动态代理程序集无需额外权限就能访问该类型,dotnet test命令即可正常运行测试用例。
内容的提问来源于stack exchange,提问作者Ali Hasan
相关产品推荐
相关产品推荐

