2011-05-26 87 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