C# 卡在控制器的moq和单元测试中

C# 卡在控制器的moq和单元测试中,c#,asp.net,unit-testing,moq,C#,Asp.net,Unit Testing,Moq,我正在尝试为exist项目编写单元测试。我总是得到SignStatus.Success和ModelState.Valid。我知道如何通过在测试中添加模型错误来处理模型状态,这将给我提供无效的模型。但我不知道为什么我在所有情况下都能成功。默认情况下,登录操作如下: [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel mode

我正在尝试为exist项目编写单元测试。我总是得到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);
    }
} 
[HttpPost]
[异名]
[ValidateAntiForgeryToken]
公共异步任务登录(LoginView模型,字符串返回URL)
{
如果(!ModelState.IsValid)
返回视图(模型);
//这不会将登录失败计入帐户锁定
//要使密码失败触发帐户锁定,请更改为shouldLockout:true
var result=wait SignInManager.PasswordSignInAsync(model.Email、model.Password、model.RememberMe、shouldllockout:false);
开关(结果)
{
案例标志状态成功:
if(String.IsNullOrEmpty(returnUrl)| |!Url.IsLocalUrl(returnUrl))
返回重定向到操作(“索引”、“主页”);
返回重定向(returnUrl);
案例标志状态锁定输出:
返回视图(“锁定”);
案例标志状态。要求验证:
return RedirectToAction(“SendCode”,new{ReturnUrl=ReturnUrl,RememberMe=model.RememberMe});
案例信号状态故障:
违约:
AddModelError(“,”登录尝试无效“);
返回视图(模型);
}
} 
这是我的测试:

[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);
}
[测试]
公共异步任务登录AccessAndReturnViewAsync()
{
loginView模型loginView=新loginView模型{电子邮件=”qwe@asd,Password=“123”,RememberMe=false};
//安排
//用户身份
var validUser=new Mock();
moqContext.Setup(x=>x.User.Identity).Returns(validUser.Object);
Setup(x=>x.Name).Returns(loginView.Email);
//应用程序服务器管理器
var user=new ApplicationUser{UserInfo=new UserInfo{
Id=336,
FirstName=“User”,
LastName=“Info”,
CountryId=1,
城市=空,
地址=空,
ZipCode=null,
电话=null,
位置=空,
PayoutTime=0,
LanguageId=3,
PayPalAllowIR=假,
LiqPayAllowIR=false
} };
var userStore=new Mock(MockBehavior.Strict);
userStore.As().Setup(x=>x.FindByIdAsync(It.IsAny()).ReturnsAsync(用户);
var userManager=newmock(userStore.Object);
//应用程序签名管理器
var authenticationManager=new Mock();
var signInManager=new Mock(userManager.Object,authenticationManager.Object);
accountController=新的accountController(userManager.Object,signInManager.Object);
var context=newcontrollercontext(moqContext.Object,new System.Web.Routing.RouteData(),accountController);
accountController.ControllerContext=上下文;
//表演
var res=await accountController.Login(loginView,“/Account/Login”);
//断言
Assert.IsNotNull(res);
}

我做错了什么?

当您没有在模拟中设置
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);
signInManager
.Setup(x=>x.PasswordSignInAsync(It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny())
.ReturnsAsync(Microsoft.AspNet.Identity.Owin.SignInStatus.Failure);

当您没有在模拟中设置
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);
signInManager
.Setup(x=>x.PasswordSignInAsync(It.IsAny(),
It.IsAny(),
It.IsAny(),
It.IsAny())
.ReturnsAsync(Microsoft.AspNet.Identity.Owin.SignInStatus.Failure);

那么您到底想测试什么?那
AccountController.Login
返回的不是null?我无法测试它,因为我有NullReferenceException。我想测试,该用户的凭据正确,用户可以登录,然后重定向到“索引”,“主页”。或者不正确的证书那么你到底想测试什么呢?那
AccountController.Login
返回的不是null?我无法测试它,因为我有NullReferenceException。我想测试,该用户的凭据正确,用户可以登录,然后重定向到“索引”,“主页”。或者是不正确的证件,它是有效的。我是否需要设置所有情况下的返回状态,而不依赖于我在操作中通过的模型?这取决于您的测试。是否确实要模拟签名管理器?
SignInManager.PasswordSignInAsync
的输入不重要,因为在单元测试和moq框架中,它是新的。我不知道怎么处理它。但控制器中的几乎所有操作都使用SignInManager和UserManager。以及User.Identity.GetUserId()和UserManager.FindById()等方法;你能推荐一些文章、书籍或课程/教程来更好地理解它的工作原理吗?我现在想不出任何具体的来源。您应该查看channel9.msdn.com和mva.microsoft.com。非常感谢。但是你能解释一下,为什么输入SignInManager.PasswordSignInAsync并不重要吗?它是有效的。我是否需要设置所有情况下的返回状态,而不依赖于我在操作中通过的模型?这取决于您的测试。是否确实要模拟签名管理器?
SignInManager.PasswordSignInAsync
的输入不重要,因为在单元测试和moq框架中,它是新的。我不知道怎么处理它。但控制器中的几乎所有操作都使用SignInManager和UserManager。及