How does MVC check POCO code first with DataAnnotations?

In my unit tests, I would like to force the code check first to POCO, which has DataAnnotations on it.

The MVC framework should do this behind the scenes, and basically I would like to know how, so I can hopefully use it.

+4
source share
2 answers

The MVC framework framework will do this behind the scenes, and basically I would like to know how, so I can hopefully use it.

This is the default middleware that is responsible for invoking model validation after it has bound it to the request values.

You can invoke the verification process manually using the ValidationContext .

Suppose you have a model:

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

and then you can unit test it:

 [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); } 

As an alternative to using DataAnnotations, you can use FluentValidation.NET to perform validation on view models. It goes well with ASP.NET MVC and allows you to unit test your validators in a very elegant way.

+5
source

I just answered a similar question .

I usually unit test setup model validation, directly calling the methods of the facade System.ComponentModel.DataAnnotations.Validator.

I wrote an article on this subject http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/

As a result, I get code like this (the article shows a cleaner and more reusable unit test base class for model verification)

 [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" }; /* ... */ } 

I don’t like trusting code to work, so I systematically write unit test for my model validation code. However, I trust the framework / model middleware to perform the validation. This unit test allows me to write a controller that trusts validation in order.

0
source

Source: https://habr.com/ru/post/1435244/


All Articles