简体   繁体   中英

Stuck with moq and unit test for Controller

I'm trying to write unit tests for exist project. I always get SignStatus.Success and ModelState.Valid. I know how to deal with model state by add model error in test, will give me invalid model. But i don't know why i have success in sign in all cases. Login Action is default, here is:

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

And there is my test:

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

What i do wrong?

When you don't setup SignInManager.PasswordSignInAsync method in your mock, it will always return the default value for output which is SignInStatus.Success

If you want other return value for your test you need to setup your SignInManager instance.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM