用于控制器的moq和单元测试

时间:2018-04-03 09:20:05

标签: c# asp.net unit-testing moq

我试图为现有项目编写单元测试。我总是得到SignStatus.Success和ModelState.Valid。我知道如何通过在测试中添加模型错误来处理模型状态,会给我无效的模型。但我不知道为什么我在所有情况下都能获得成功。登录操作是默认的,这是:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
        return View(model);

    // This doesn't count login failures towards account lockout
    // To enable password failures to trigger account lockout, change to shouldLockout: true
    var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
        case SignInStatus.Success:
            if (String.IsNullOrEmpty(returnUrl) || !Url.IsLocalUrl(returnUrl))
                return RedirectToAction("Index", "Home");
            return Redirect(returnUrl);
        case SignInStatus.LockedOut:
            return View("Lockout");
        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Invalid login attempt.");
            return View(model);
    }
} 

还有我的测试:

[Test]
public async Task LogInSuccessAndReturnViewAsync()
{
    LoginViewModel loginView = new LoginViewModel { Email = "qwe@asd", Password = "123", RememberMe = false };
    //Arrange
    //User.Identity
    var validUser = new Mock<IIdentity>();  
    moqContext.Setup(x => x.User.Identity).Returns(validUser.Object);
    validUser.Setup(x => x.Name).Returns(loginView.Email);

    //ApplicationUserManager
    var user = new ApplicationUser { UserInfo = new UserInfo {
        Id = 336,
        FirstName = "User",
        LastName ="Info",
        CountryId = 1,
        City = null,
        Address = null,
        ZipCode = null,
        Tel = null,
        Position = null,
        PayoutTime = 0,
        LanguageId = 3,
        PayPalAllowIR = false,
        LiqPayAllowIR = false
    } };
    var userStore = new Mock<IUserStore<ApplicationUser>>(MockBehavior.Strict);
    userStore.As<IUserStore<ApplicationUser>>().Setup(x => x.FindByIdAsync(It.IsAny<string>())).ReturnsAsync(user);
    var userManager = new Mock<ApplicationUserManager>(userStore.Object);

    //ApplicationSignInManager
    var authenticationManager = new Mock<IAuthenticationManager>();
    var signInManager = new Mock<ApplicationSignInManager>(userManager.Object, authenticationManager.Object);

    accountController = new AccountController(userManager.Object, signInManager.Object);
    var context = new ControllerContext(moqContext.Object, new System.Web.Routing.RouteData(), accountController);
    accountController.ControllerContext = context;

    //Act
    var res = await accountController.Login(loginView,"/Account/Login");

    //Assert
    Assert.IsNotNull(res);
}

我做错了什么?

1 个答案:

答案 0 :(得分:2)

如果您未在模拟中设置SignInManager.PasswordSignInAsync方法,它将始终返回输出的默认值SignInStatus.Success

如果您想要测试的其他返回值,则需要设置SignInManager实例。

signInManager
    .Setup(x => x.PasswordSignInAsync(It.IsAny<string>(),
                                      It.IsAny<string>(),
                                      It.IsAny<bool>(),
                                      It.IsAny<bool>()))
         .ReturnsAsync(Microsoft.AspNet.Identity.Owin.SignInStatus.Failure);