C# 卡在控制器的moq和单元测试中
我正在尝试为exist项目编写单元测试。我总是得到SignStatus.Success和ModelState.Valid。我知道如何通过在测试中添加模型错误来处理模型状态,这将给我提供无效的模型。但我不知道为什么我在所有情况下都能成功。默认情况下,登录操作如下: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
[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。及