How to unit test DataAnnotationsModelBinder in ASP.NET MVC 2

I am using ASP.NET MVC 2 with DataAnnotation attributes sprinkled with such properties:

public class LogOnViewModel { [Required] public string UserName { get; set; } [Required] public string Password { get; set; } [Required] public string Domain { get; set; } } 

I have a unit test that checks that the current view is displayed when the check completes. However, I manually add errors to ModelState to make it work:

  [Test] public void TestThatLogOnActionRedirectsToLogOnViewIfValidationFails() { //create a invalid view model var model = new LogOnViewModel {UserName = "jsmith"}; //Can I avoid doing this manually? //populate Model State Errors Collection _accountController.ModelState.AddModelError("FirstName", "First Name Required"); _accountController.ModelState.AddModelError("LastName", "Last Name Required"); var result = _accountController.LogOn(model); result.AssertViewRendered() .ForView(Constants.Views.LogOn) .WithViewData<LogOnViewModel>(); } 

Is there a way to interact with ModelBinder directly or indirectly in unit test? For instance:

  [Test] public void TestThatLogOnActionRedirectsToLogOnViewIfValidationFails() { //create a invalid view model var model = new LogOnViewModel {UserName = "jsmith"}; //validate model //not sure about the api call... var validationResults = new DataAnnotationsModelBinder().Validate(model); _accountController.ModelState.Merge(validationResults); var result = _accountController.LogOn(model); result.AssertViewRendered() .ForView(Constants.Views.LogOn) .WithViewData<LogOnViewModel>(); } 
+3
source share
2 answers

Brad Wilson has a nice blog about DataAnnotationsModelBinder, including how to unit test it: http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html

+1
source

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/1435246/


All Articles