簡體   English   中英

單元測試模擬 ControllerContext HttpContext 沒有為類型“Microsoft.AspNetCore.Mvc.View...ITempDataDictionaryFactory”注冊服務

[英]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();
}

如您所見,它使用HttpContextSignOutAsync

我嘗試了很多解決方案,例如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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM