c# - 在 asp.net mvc 3 中登录的单元测试

标签 c# asp.net 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 语句和其他条件逻辑。也不要在测试中使用具体类。如果这个测试会失败,你怎么知道为什么?什么坏了 - Controller 或 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<IMembershipService> membership = new Mock<IMembershipService>();
    membership.Setup(m => m.ValidateUser(It.IsAny<string>(), It.IsAny<string>()))
              .Returns(false);
    Mock<IFormsService> forms = new Mock<IFormsService>();
    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."));
}

有趣的是,您不关心传递给 Controller ​​的登录信息是什么。您模拟来自成员(member)服务的响应,它说登录不正确。

更多测试:

[Test]
public void ShouldRedisplayViewWhenModelIsNotValid()
{
   // Arrange        
   Mock<IMembershipService> membership = new Mock<IMembershipService>();
   Mock<IFormsService> forms = new Mock<IFormsService>();
   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<IMembershipService> membership = new Mock<IMembershipService>();
  membership.Setup(m => m.ValidateUser(It.IsAny<string>(), It.IsAny<string>()))
             .Returns(true);
   Mock<IFormsService> forms = new Mock<IFormsService>();
   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"));
}

关于c# - 在 asp.net mvc 3 中登录的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11612608/

相关文章:

c# - 检查 Int32.TryParse 的更简单方法

c# - 返回列表 1 和列表 2 中的项目匹配的列表

c# - 缩放图像,但保持其比例

asp.net - 有什么办法可以使用 web.config 转换做 "Replace Or Insert"吗?

c# - 如何为 MYSQL 存储过程设置日志记录

c# - 如何动态地向匿名对象添加属性?

c# - 'Press Any key to continue.... '的解释

c# - AWS SQS,如何计算消息属性的 MD5 消息摘要

asp.net - 将项目开发提升到一个新的水平

javascript - 如何将 JavaScript 与 Razor 代码混合使用