【发布时间】:2020-03-17 13:55:36
【问题描述】:
我有一个使用 Identity 的 .NET Core 3.1 项目。对于Login 页面处理程序,我添加了一行代码,在用户登录后,它会根据用户的 IP 地址更新用户位置:
_locationRepository.UpdateUserLocationAsync(HttpContext.Connection.RemoteIpAddress);
完整代码
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_locationRepo.UpdateUserLocation(HttpContext.Connection.RemoteIpAddress);
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
我的问题是在编写单元测试时,我不知道如何正确模拟HttpContext。无论我尝试了什么,我都会不断收到空引用异常。
var httpContext = new Mock<HttpContext>();
httpContext.Setup(x => x.Connection.RemoteIpAddress).Returns(new IPAddress(16885952));
如何模拟RemoteIpAddress?
【问题讨论】:
-
展示如何将上下文分配给被测主题(PageModel)
-
你从哪里得到异常?
-
在控制器中模拟 HttpContext 并非易事,因为它是一个只读属性。 Here 您可以阅读原因。您最好的选择可能是从控制器中抽象出上下文属性。
-
我使用的是剃须刀页面,而不是控制器。这会让事情变得更容易吗?
-
其实有!请查看 MS 文档 (docs.microsoft.com/en-us/aspnet/core/test/…) 和示例 (github.com/dotnet/AspNetCore.Docs/blob/master/aspnetcore/test/…) 我的错,没有注意到它的 RazorPages 应用程序。
标签: c# unit-testing asp.net-core asp.net-identity