2011-05-26 85 views
0

我正在使用Specflow,nunit和moq在学习SpecFlow时测试默认的MVC2应用程序注册。Specflow with MVC Model Validation问题

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

步骤

[Given(@"The user has not entered the username")] 
     public void GivenTheUserHasNotEnteredTheUsername() 
     { 
      _registerModel = new RegisterModel 
      { 
       UserName = null, 
       Email = "[email protected]", 
       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 = "[email protected]", 
       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不匹配,但我不明白为什么所有其他的测试,其中包括缺少确认密码测试(等同于丢失的密码测试),他们工作正常。

任何想法?

特点

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

  • 方案:如果密码丢失

  • 注册应返回的错误假设用户还没有进入 密码
  • 当他点击注册按钮
  • 那么他应该被显示的错误消息“'密码'必须至少有12个字符,长度至少为 ”。 “密码”

UPDATE 好似乎ValidatePasswordLengthAttribute在帐户模型无法initilise Membership.Provider因为我没有在我的app.config ConnectionString中。 Pembership.Provider现在是否连接到成员资格数据库?

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

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

问题是,他们不是每次都以相同的顺序返回,所以测试是片状的。 如何重写我的场景并进行测试以解释此情况?我仍然可以保留一个“Then”方法,还是需要创建一个新方法?

谢谢。

回答

0

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

我已经更新了其检查正确的错误消息的断言:

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

仍然不确定的Membership.Provider是否击中DB