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 回答