[英]No service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered
[英]Unit Tests Mock ControllerContext HttpContext No service for type 'Microsoft.AspNetCore.Mvc.View...ITempDataDictionaryFactory' has been registered
在我的测试项目中,我将 xUnit 与 Moq 一起使用。
现在我想在 controller 中对这些代码进行单元测试:
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
return View();
}
如您所见,它使用HttpContext
的SignOutAsync
。
我尝试了很多解决方案,例如ASP.NET MVC - 单元测试,mocking HttpContext 没有使用任何模拟框架,但对我不起作用,因为我无权访问HttpRequestBase
使用 Moq,我试图模拟这个HttpContext
,所以我尝试了这个:
public static Mock<HttpContext> GenerateFakeHttpContext()
{
var mockHttpContext = new Mock<HttpContext>();
var authServiceMock = new Mock<IAuthenticationService>();
authServiceMock.Setup(_ => _.SignOutAsync(
It.IsAny<HttpContext>(),
It.IsAny<string>(),
It.IsAny<AuthenticationProperties>()))
.Returns(Task.FromResult((object)null));
var serviceProviderMock = new Mock<IServiceProvider>();
serviceProviderMock.Setup(_ => _.GetService(typeof(IAuthenticationService)))
.Returns(authServiceMock.Object);
mockHttpContext.Setup(x => x.RequestServices)
.Returns(serviceProviderMock.Object);
return mockHttpContext;
}
灵感来自这个问题: MSTest: Unit Testing HttpContext.SignoutAsync for the logout ,经过多项研究。
测试方法是这样的:
public async Task Login_ShouldSignOutToClearCoockies_WhenReturnUrlIsNullOrNotNull()
{
//Arrange
_sutAccountController
.ControllerContext.HttpContext = TestsHelper.GenerateFakeHttpContext().Object;
//Act
var result = await _sutAccountController.Login(null);
//Assert
result.Should().NotBeNull();
}
但在运行时我得到这个异常:
Duration: 367 ms
Message:
System.InvalidOperationException : No service for type 'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered.
Stack Trace:
ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
Controller.get_TempData()
Controller.View(String viewName, Object model)
Controller.View(String viewName)
Controller.View()
AccountController.Login(String returnUrl) line 38
AccountControllerTests.Login_ShouldSignOutToClearCoockies_WhenReturnUrlIsNullOrNotNull() line 46
--- End of stack trace from previous location ---
如果有更好的方法来模拟HttpContext 。
谢谢。
我终于找到了 mocking controller TempData 的解决方案
来源: MSTest 中 ASP.NET 核心中的 Mocking TempData
var tempData = new Microsoft.AspNetCore.Mvc.ViewFeatures
.TempDataDictionary(httpContext, Mock.Of<Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataProvider>());
tempData["ReturnUrl"] = "";
_sutController.ControllerContext.HttpContext = httpContext;
_sutController.TempData = tempData
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.