【问题标题】:Specflow with MVC Model Validation Issue带有 MVC 模型验证问题的 Specflow
【发布时间】:2011-05-26 14:02:21
【问题描述】:

在学习 SpecFlow 时,我正在使用 Specflow、nunit 和 moq 来测试默认的 MVC2 应用程序注册。

我有以下步骤来检查是否没有输入用户名和密码。

步骤

[Given(@"The user has not entered the username")]
        public void GivenTheUserHasNotEnteredTheUsername()
        {   
            _registerModel = new RegisterModel
            {
                UserName = null,
                Email = "test@dummy.com",
                Password = "test123",
                ConfirmPassword = "test123"
            };      
        }

[Given(@"The user has not entered the password")]
        public void GivenTheUserHasNotEnteredThePassword()
        {
            _registerModel = new RegisterModel
            {
                UserName = "user" + new Random(1000).NextDouble().ToString(),
                Email = "test@dummy.com",
                Password = string.Empty,
                ConfirmPassword = "test123"
            };  
        }

[When(@"He Clicks on Register button")]
        public void WhenHeClicksOnRegisterButton ()
        {
            _controller.ValidateModel(_registerModel);
            _result = _controller.Register(_registerModel);
        }

[Then(@"He should be shown the error message ""(.*)""  ""(.*)""")]
        public void ThenHeShouldBeShownTheErrorMessage(string errorMessage, string field)
        {
            Assert.IsInstanceOf<ViewResult>(_result);
            var view = _result as ViewResult;
            Assert.IsNotNull(view);
            Assert.IsFalse(_controller.ModelState.IsValid);
            Assert.IsFalse(view.ViewData.ModelState.IsValidField(field));
            Assert.IsTrue(_controller.ViewData.ModelState.ContainsKey(field));          

            Assert.AreEqual(errorMessage,
            _controller.ModelState[field].Errors[0].ErrorMessage);
        }

强制验证的扩展方法

public static class Extensions
    {
        public static void ValidateModel<T> ( this Controller controller, T modelObject )
        {
            if (controller.ControllerContext == null)
                controller.ControllerContext = new ControllerContext();

            Type type = controller.GetType();
            MethodInfo tryValidateModelMethod =
                type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(
                    mi => mi.Name == "TryValidateModel" && mi.GetParameters().Count() == 1).First();

            tryValidateModelMethod.Invoke(controller, new object[] { modelObject });
        }
    }`

我不明白为什么密码丢失测试在以下几行中失败。

    Assert.IsFalse(view.ViewData.ModelState.IsValidField(field));
    Assert.IsTrue(_controller.ViewData.ModelState.ContainsKey(field));

我注意到返回的错误消息是因为 Password 和 ConfirmPassword 不匹配,但我不明白为什么所有其他测试,包括 Missing Confirm Password 测试(与 Missing Password 测试相同)都可以正常工作。

有什么想法吗?

特点

  • 场景:如果用户名丢失,注册应该返回错误
  • 鉴于用户尚未输入用户名
  • 当他点击注册按钮时
  • 然后他应该看到错误 消息“用户名字段是必需的。” “用户名”

  • 场景:如果密码丢失,注册应该返回错误

  • 鉴于用户尚未输入 密码
  • 当他点击注册按钮时
  • 然后他应该看到错误消息“'密码'必须至少 6 个字符长。" "密码"

更新 好的,帐户模型中的 ValidatePasswordLengthAttribute 似乎无法初始化 Membership.Provider,因为我的 app.config 中没有连接字符串。 Pembership.Provider 现在是否连接到会员数据库?

我已经添加了连接字符串,但现在测试通过了 50% 的时间,因为它返回两个错误:

  • 需要密码
  • 密码长度必须为 6 个字符。

问题是它们不是每次都以相同的顺序返回,所以测试很不稳定。 我该如何重写我的场景和测试来解决这个问题?我还能保留一个“Then”方法还是需要创建一个新方法?

谢谢。

【问题讨论】:

    标签: asp.net-mvc-2 nunit moq specflow


    【解决方案1】:

    我必须将 AccountService 的连接字符串添加到 nunit 使用的 App.config 中。这导致 ValidatePasswordLengthAttribure 出现错误。

    我已将检查正确错误消息的 Assert 更新为:

    Assert.AreEqual(errorMessage, 
                _controller.ModelState[field].Errors.First(e => e.ErrorMessage == errorMessage).ErrorMessage);
    

    仍然不确定 Membership.Provider 是否正在访问数据库

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多