Specflow与MVC模型验证问题

我在学习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));

我注意到返回的错误信息是密码和ConfirmPassword不匹配,但我不明白为什么所有其他测试,包括缺少确认密码测试(与缺少密码测试相同),他们工作正常。

有任何想法吗?

特征

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

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

  • 鉴于用户没有输入密码
  • 当他点击注册按钮时
  • 然后他应该显示错误消息“'密码'必须至少6个字符长。” “密码”
  • 更新好吧,似乎帐户模型中的ValidatePasswordLengthAttribute无法初始化Membership.Provider因为我的app.config中没有连接字符串。 Pembership.Provider现在是否连接到成员资格数据库?

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

  • 要求输入密码
  • 密码必须是6个字符。
  • 问题是,他们不是每次都以相同的顺序返回,所以测试是片状的。 我如何重写我的场景并进行测试来解释这一点? 我仍然可以保留一个“Then”方法,还是需要创建一个新方法?

    谢谢。


    我不得不将连接字符串AccountService添加到nunit使用的App.config中。 这在ValidatePasswordLengthAttribure上导致错误。

    我更新了检查正确的错误信息的Assert:

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

    仍然不确定Membership.Provider是否正在击中数据库

    链接地址: http://www.djcxy.com/p/56599.html

    上一篇: Specflow with MVC Model Validation Issue

    下一篇: MVC Validation in Model