Yesterday I wrote about ASP.NET MVC, TDD and AutoMapper, and how you can use them together in a DDD application. Today I thought I would follow up and explain how to apply these techniques to another important (but boring) part of any web application: user input validation.
To achieve this, we are using Fluent Validation, a validation framework that lets you easily set up validation rules using a fluent syntax:
If you think about it, validation and view model mapping have similar footprints in the application. They both:
Live in the application services layer
May invoke domain services
Use third-party libraries
Have standalone fluent configurations
Have standalone tests
Are injected into the application services
Let's see how it all fits together starting at the outermost layer, the controller.
As usual, the controller is pretty thin, delegating all responsibility (including performing any required validation) to an application service that handles new user registration. If validation fails, all our controller has to do is catch an exception and append the validation messages contained within to the model state to tell the user any mistakes they made.
The UserRegistrationForm validator is injected into the application service along with any others. Just like AutoMapper, we can now test both the controller, validator and application service separately.
Testing the user registration form validation rules
You can even inject dependencies into the validator and mock them out for testing. For example, in this app the validator calls an IUsernameAvailabilityService to make sure the chosen username is still available.
Testing the user registration service
This validation code is now completely isolated, and we can mock out the entire thing when testing the application service:
Testing the accounts controller
With validation out of the way, all we have to test on the controller is whether or not it appends the validation errors to the model state. Here are the fixtures for the success/failure scenarios:
This post has been a bit heavier on code than usual, but hopefully it is enough to get an idea of how easy it is to implement Fluent Validation in your ASP.NET MVC application.