4

在我的单元测试中,我想强制验证具有 DataAnnotations 的代码优先 POCO。

MVC框架一定是在幕后做的,基本上我想知道怎么做,所以我希望可以利用它。

4

2 回答 2

5

MVC 框架在幕后进行,基本上我想知道如何,所以我希望可以利用它。

它是默认的模型绑定器,一旦它从请求值绑定模型,它就负责调用模型的验证。

您可以使用ValidationContext.

假设您有一个模型:

public class Foo
{
    [Required(ErrorMessage = "the Bar is absolutely required")]
    public string Bar { get; set; }
}

然后你可以对它进行单元测试:

[TestMethod]
public void The_Bar_Is_Required()
{
    // arrange
    var foo = new Foo();
    var results = new List<ValidationResult>();
    var context = new ValidationContext(foo, null, null);

    // act
    var actual = Validator.TryValidateObject(foo, context, results);

    // assert
    Assert.IsFalse(actual);
}

除了使用 DataAnnotations,您还可以使用FluentValidation.NET对您的视图模型执行验证。它与 ASP.NET MVC 很好地集成,它允许您以非常优雅的方式对验证器进行单元测试。

于 2012-09-20T09:56:21.447 回答
0

我刚刚回答了一个类似的问题

我通常通过直接调用 System.ComponentModel.DataAnnotations.Validator 的外观方法来对我的模型验证设置进行单元测试。

我写了一篇关于这个主题的文章http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/

我最终得到了这样的代码(这篇文章展示了一个用于模型验证的更简洁且可重用的单元测试基类)

[Test]
[TestCaseSource("ValidationRule_Source")]
public void ValidationRule(ValidateRuleSpec spec) {
    // Arrange
    var model = CreateValidPersonModel();
    // Apply bad valud
    model.GetType().GetProperty(spec.MemberName).SetValue(model, spec.BadValue);

    // Act
    var validationResults = new List<ValidationResult>();
    var success = Validator.TryValidateObject(model, new ValidationContext(model), validationResults, true);

    // Assert
    Expect(success, False);
    Expect(validationResults.Count, EqualTo(1));
    Expect(validationResults.SingleOrDefault(r => r.MemberNames.Contains(spec.MemberName)), Not.Null);
}

public IEnumerable<ValidateRuleSpec> ValidationRule_Source() {
    yield return new ValidateRuleSpec() {
        BadValue = null,
        MemberName = "FirstName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = string.Empty,
        MemberName = "FirstName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = null,
        MemberName = "LastName"
    };
    /* ... */
}

我不喜欢相信代码可以正常工作,所以我系统地为我的模型验证代码编写单元测试。但是,我确实信任框架/模型绑定器来执行验证。这个单元测试允许我编写信任验证正常的控制器。

于 2013-06-21T09:21:45.907 回答