C# 模拟ASP.NET标识的单元测试登录失败
我正在使用Moq和Microsoft的测试工具为使用ASP.NET标识的ASP.NET MVC 5应用程序编写一个单元测试。测试需要在登录后操作中模拟登录失败,以便从myC# 模拟ASP.NET标识的单元测试登录失败,c#,asp.net,asp.net-mvc,unit-testing,asp.net-identity,C#,Asp.net,Asp.net Mvc,Unit Testing,Asp.net Identity,我正在使用Moq和Microsoft的测试工具为使用ASP.NET标识的ASP.NET MVC 5应用程序编写一个单元测试。测试需要在登录后操作中模拟登录失败,以便从myAccountController的SignInManager.PasswordSignInAsync方法生成SignInStatus.failure: [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult
AccountController的SignInManager.PasswordSignInAsync
方法生成SignInStatus.failure
:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login([Bind(Include = "Email,Password,RememberMe")]
LoginViewModel model, string returnUrl)
{
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password,
model.RememberMe, shouldLockout: true);
switch (result)
{
case SignInStatus.Success:
return Redirect(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
这是我的测试方法:
[TestMethod]
public async Task NoViewReturnedForFailedLogin()
{
// Arrange
var claimsIdentity = new ClaimsIdentity();
claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, "fake@fake.org"));
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
SetContexts(claimsPrincipal);
var vm = new LoginViewModel
{
Email = "faker@gmail.com",
Password = "Faker9999!",
RememberMe = false
};
_controllerContextMock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(vm.Email);
_controllerContextMock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(false);
// Act
var result = await _controller.Login(vm, "http://www.google.com") as RedirectToRouteResult;
// Assert
// ? What do I assert?
}
如您所见,我有mockuserStore
、userManager
、authenticationManager
和signInManager
。如果我单步执行Login
操作,result
始终返回SignInStatus.Success
有没有办法让它失败?测试应该断言什么?您需要为SignInManager.PasswordSignInAsync设置模拟以返回其他内容SeSignInManager.setup(p=>PasswordSignInAsync().ReturnsAsync(SignInStatus.Failure);您模拟的依赖项太多,而测试中的方法仅依赖于SignInManager
。请设置该依赖项,使其按照测试和您的完成所需的方式运行。至于要断言的内容,请查看预期的代码路径,并断言结果符合预期。从创建的模拟中,似乎可以看到您的帐户控制器与实现问题紧密耦合,这也解释了为什么必须模拟如此多的依赖关系。类应该依赖于抽象而不是具体的实现。设置的数量表明您在错误的级别或错误的事情上进行测试。请后退一步,思考您实际要测试的内容以及原因。如果您尝试ng测试登录管理器
-这是标识库的一部分,已经为您进行了测试。
[TestMethod]
public async Task NoViewReturnedForFailedLogin()
{
// Arrange
var claimsIdentity = new ClaimsIdentity();
claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, "fake@fake.org"));
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
SetContexts(claimsPrincipal);
var vm = new LoginViewModel
{
Email = "faker@gmail.com",
Password = "Faker9999!",
RememberMe = false
};
_controllerContextMock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(vm.Email);
_controllerContextMock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(false);
// Act
var result = await _controller.Login(vm, "http://www.google.com") as RedirectToRouteResult;
// Assert
// ? What do I assert?
}