在asp.net mvc 3中登录的unit testing

我使用现有的AccountController(由MVC制作)测试登录方法时遇到问题…

我有这个简单的测试方法:

[TestMethod] public void LogOnTest1() { AccountController controller = new AccountController(); LogOnModel logonModel = new LogOnModel(); logonModel.UserName = "test"; logonModel.Password = "test1234"; if ( controller.MembershipService == null ) { controller.MembershipService = new AccountMembershipService(); } if ( controller.FormsService == null ) { controller.FormsService = new FormsAuthenticationService(); } var result = controller.LogOn( logonModel, "" ) as ViewResult; Assert.AreEqual( "Index", result.ViewName ); } 

AccountController定义的方法:

 [HttpPost] public ActionResult LogOn( LogOnModel model, string returnUrl ) { if ( ModelState.IsValid ) { if ( MembershipService.ValidateUser( model.UserName, model.Password ) ) { FormsService.SignIn( model.UserName, model.RememberMe ); if ( !string.IsNullOrEmpty( returnUrl ) ) { return Redirect( returnUrl ); } else { return RedirectToAction( "Index", "Home" ); } } else { ModelState.AddModelError( "", "The user name or password provided is incorrect." ); } } // If we got this far, something failed, redisplay form return View( model ); } 

我没有定义/修改上述方法。 刚刚创建一个asp.net mvc项目时创建。

问题是在线

if ( MembershipService.ValidateUser( model.UserName,model.Password ) ) {

虽然我提供了正确的登录信息,但它总是返回false。

我的错误在哪里?

首先,不要在测试中使用if语句和其他条件逻辑。 也不要在测试中使用具体类。 如果这个测试失败了,你怎么知道为什么? 什么被打破 – 控制器或AccountMembershipService ? 使用可以模拟的抽象依赖项。

 public class AccountController : Controller { private IMembershipService _membershipService; private IFormsService _formsService; public AccountController(IMembershipService membershipService, IFormsService formsService) { _membershipService = membershipService; _formsService = formsService; } public ActionResult LogOn(LogOnModel model, string returnUrl) { // implementation goes here } } 

而你的测试:

 [Test] public void ShouldNotAcceptInvalidUser() { // Arrange Mock membership = new Mock(); membership.Setup(m => m.ValidateUser(It.IsAny(), It.IsAny())) .Returns(false); Mock forms = new Mock(); var logonModel = new LogOnModel() { UserName = "", Password = "" }; var controller = new AccountController(membership.Object, forms.Object); // Act var result = controller.LogOn(logonModel, "") as ViewResult; // Assert Assert.That(result.ViewName, Is.EqualTo("Index")); Assert.False(controller.ModelState.IsValid); Assert.That(controller.ModelState[""], Is.EqualTo("The user name or password provided is incorrect.")); } 

有趣的是,您不关心传递给控制器​​的登录信息。 您模拟会员服务的响应,该服务表示登录不正确。

几个测试更多:

 [Test] public void ShouldRedisplayViewWhenModelIsNotValid() { // Arrange Mock membership = new Mock(); Mock forms = new Mock(); var model = new LogOnModel() { UserName = "", Password = "" }; var controller = new AccountController(membership.Object, forms.Object); controller.ModelState.AddModelError("key", "error message"); // Act var result = controller.LogOn(model, "") as ViewResult; // Assert Assert.That(result.ViewName, Is.EqualTo("LogOn")); } [Test] public void ShouldSignInAndRedirectToIndex() { // Arrange Mock membership = new Mock(); membership.Setup(m => m.ValidateUser(It.IsAny(), It.IsAny())) .Returns(true); Mock forms = new Mock(); var model = new LogOnModel() { UserName = "", Password = "" }; var controller = new AccountController(membership.Object, forms.Object); controller.ModelState.AddModelError("key", "error message"); // Act var result = controller.LogOn(model, "") as ViewResult; // Assert forms.Verify(f => f.SignIn(model.UserName, model.RememberMe)); Assert.That(result.ViewName, Is.EqualTo("Index")); }