0

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文字の長さである必要があります」というエラーメッセージが表示されます。"パスワード"

UPDATE Okは、app.configMembership.Providerに接続文字列がなかったため、アカウントモデルのValidatePasswordLengthAttributeを初期化できなかったようです。Pembership.ProviderはメンバーシップDBに接続していますか?

接続文字列を追加しましたが、2つのエラーが返されるため、テストは50%の確率で合格します。

  • パスワードが必要
  • パスワードは6文字の長さである必要があります。

問題は、それらが毎回同じ順序で返されるわけではないため、テストが不安定になることです。シナリオを書き直して、これを説明するためにテストするにはどうすればよいですか?1つの「Then」メソッドを引き続き使用できますか、それとも新しいメソッドを作成する必要がありますか?

ありがとう。

4

1 に答える 1

0

nunitが使用するApp.configにAccountServiceの接続文字列を追加する必要がありました。これにより、ValidatePasswordLengthAttribureでエラーが発生していました。

正しいエラーメッセージをチェックするAssertを次のように更新しました。

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

Membership.ProviderがDBにヒットしているかどうかはまだわかりません

于 2011-05-26T16:57:11.470 に答える