提问人:OutstandingBill 提问时间:11/9/2023 最后编辑:OutstandingBill 更新时间:11/10/2023 访问量:46
模拟 HttpContext 时,SignOutAsync 失败
When mocking HttpContext, SignOutAsync fails
问:
我正在使用 Microsoft.AspNetCore.Authentication.AuthenticationHttpContextExtensions。SignOutAsync
在我的单元测试中,我在该扩展方法的某个地方得到了一个,它说ArgumentNullException
值不能为 null。(参数 'provider')
Message:
System.ArgumentNullException : Value cannot be null. (Parameter 'provider')
Stack Trace:
ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
AuthenticationHttpContextExtensions.SignOutAsync(HttpContext context, String scheme, AuthenticationProperties properties)
AuthenticationHttpContextExtensions.SignOutAsync(HttpContext context, String scheme)
AccountController.SignOut() line 123
AccountControllerTests.MyUnitTest() line 456
--- End of stack trace from previous location ---
我没有直接提供“provider”,因此我假设扩展方法是从 HttpContext 构建的。
我的测试中的 HttpContext 是使用 Moq 创建的:
var httpContext = new Mock<HttpContext>();
有没有办法哄骗我的模拟为“提供者”提供值?我是否需要切换到 DefaultHttpContext,并为 ?(很棘手,因为 DefaultHttpContext 不可模拟。ServiceScopeFactory
答:
如果你看一下源代码,最终会尝试调用一个私有方法,并且会尝试调用。SignOutAsync
GetAuthenticationService
context.RequestServices.GetService<IAuthenticationService>()
泛型是一个扩展方法,所以你的 null 实际上是 。 是抽象的,所以它将由 Moq 实现,默认情况下在松散的 mock 上,它只会返回 null。哎呀,你的崩溃了。GetService
provider
RequestServices
RequestServices
HttpContext
所以,可以设置它:
IServiceProvider serviceProvider = /*...*/;
httpContext.SetupGet(x => x.RequestServices).Returns(serviceProvider);
但到那时,你可以只使用 a 并设置提供程序:DefaultHttpContext
var httpContext = new DefaultHttpContext
{
RequestServices = serviceProvider
};
现在,您所需要的只是一个服务提供商。为此,请参阅此问题(您可以模拟一个问题,也可以从 ,创建一个问题)。ServiceCollection
评论
ArgumentNullException
SignOutAsync
IHost
IServiceProvider
ConfigureServices