16

ASP.NET MVC 3 と DataAnnotations を使用するプロジェクトに参加しています。ViewModels クラスに DataAnnotations があります。

これらの検証のための単体テストをどのように作成しますか?

ビューモデルの例:

public class AchievementVM
{
    [Required(ErrorMessage = "The title field is required.")]
    [StringLength(100, ErrorMessage = "Title must be 100 characters or less.")]
    public string Title { get; set; }
}

ありがとう!

4

3 に答える 3

16

.NET フレームワークには、検証ロジックを分離して実行できるValidatorクラスが付属しています。テストするコードは次のようになります。

var achievement = new AchievementVM();
var context = new ValidationContext(achievement, 
    serviceProvider: null, items: null);
var results = new List<ValidationResult>();

var isValid = Validator.TryValidateObject(achievement, context, results, true);

Assert.IsTrue(results.Any(vr => vr.ErrorMessage == "The title field is required."));

achievement.Title = "Really really long title that violates "
    + "the range constraint and should not be accepted as "
    + "valid input if this has been done correctly.";

Validator.TryValidateObject(achievement, context, results, true);

Assert.IsTrue(results.Any(vr => vr.ErrorMessage == "Title must be 100 characters or less."));

カスタム ユーティリティで属性の存在を検索する必要はありません。Validator クラスが作業を行い、MVC インフラストラクチャと同じように ValidationResult コレクションを設定します。

この方法に関する優れた記事は、K. Scott Allen のブログにあります。

于 2012-08-16T18:40:23.063 に答える
4

これらのアノテーションは非常に宣言的であるため、メソッドにアノテーションが付けられていることを (リフレクションで) チェックするだけの単体テストを作成する意味はほとんどありません。テストは製品コードを複製するだけです。そして、フレームワークが期待する方法でアノテーションが使用されていない可能性が残ります (おそらく、アノテーションが間違っているか、間違った場所にあるか、追加の構成が欠落している可能性があります)。

したがって、意味のあるテストは単体テストではなく、システムが注釈を正しく検出していることを確認する統合テストです。妥当な速度を維持するために、フレームワークのインスタンス化をできる限り少なくして、これらの統合テストをできる限り焦点を絞ったものにするようにしてください (これには、フレームワーク - RTFSに関する深い知識が必要です)。少なくとも、HTML を解析し、無効なデータがフィールドに入力されたときに検証エラーが表示されることを確認することで、エンド ツー エンドのテストで注釈が正しく使用されていることを確認できます。

検証が有効になっていることを確認するために、いくつかの統合/エンド ツー エンド テストを作成する必要があります。すべてのフィールドが同じように機能する場合、すべてのフィールドをテストする必要はありません。

于 2012-08-08T00:04:56.830 に答える
1

ここを参照してください:単体テスト ASP.NET DataAnnotations 検証

また、リフレクションを使用して、クラスのプロパティに必要な属性があるかどうかを確認できます。

于 2012-08-07T23:42:04.740 に答える