Archive for the ‘Testing’ Category.

ASP.Net MVC, Fluent Validation and testing

I am finally coming to the end of a project, and I thought it would be good to write a little post on how we have managed to set up our fluent validation for our MVC project. In the start we did some research into how to go about performing validation, and found a number of recommendations. But all involved using data annotations. In this post, I will show you how I set up fluent validation, to work smoothly with my MVC 2 project. I create a custom model binder to validate view models and show how to validate a registration using fluent validation. Finally I show how to unit test the validation rules I needed for registration.

To start with, there are some problems I have with data annotations

1 – Too many annotations make your model s look ugly. Take this example .

public class Product {

      public int Id { get ; set ; }


      [Required]
      [StringLength(10)]
      public string Name { get; set; }

      [Required]
      public string Description { get; set; }

      [DisplayName("Price")]
      [Required]
      [RegularExpression(@"^\$?\d+(\.(\d{2}))?$")]
      public decimal UnitPrice { get; set; }
     }

Now wouldn’t it be nice to have your model/entity just look like this.

public class Product
{
      public int Id { get; set; }
      public string Name { get; set; }
      public string Description { get; set; }
      public decimal UnitPrice { get;set; }
}

2 – Complex data validation with attributes makes your code get even more ugly. Take a lot at this example showing how to achieve slightly more complexity with data annotations. Now trying to reuse and share attributes seem to make things more and more complex….

3- I think there may be a performance issue, as we need to extract the validation attributes using reflection. Now, while these are simple models, with simple validation rules, we may not notice the performance degrading, but I am sure that with numerous complex attributes, things might run a little slow. (I need to prove this though – maybe when I get time, I will write some tests – I could be wrong here, things might change in MVC 3)

So after looking at some examples, such as xVal –dead now, Entity validation with visitors and extension methods these all did the job, but I would need to write lots of helpers, what I needed was some kind of framework for validation. Then I found fluent validation.

Linking MVC with Fluent Validation

So let us look at how we set our MVC project . Firstly, I want to automate the validation, so that any errors are automically added to the models state. With some help from Jeremy I set up an customised BindAndValidate attribute. Here is a simplified attribute we started with.

    1     public class BindAndValidateAttribute : CustomModelBinderAttributeIModelBinder {

    2         AttributedValidatorFactory validatorFactory = new AttributedValidatorFactory();

    3 

    4         public override IModelBinder GetBinder() {

    5             return this;

    6         }

    7 

    8         public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {

    9 

   10             var innerBinder = new DefaultModelBinder();

   11             var boundInstance = innerBinder.BindModel(controllerContext, bindingContext);

   12             if (boundInstance != null)

   13                 ValidateInstance(boundInstance, bindingContext);

   14 

   15             return boundInstance;

   16         }

   17 

   18         void ValidateInstance(object instance, ModelBindingContext context) {

   19             var validator = validatorFactory.GetValidator(context.ModelType);

   20             if (validator != null)

   21             {

   22                 var result = validator.Validate(instance);

   23                 result.AddToModelState(context.ModelState, "");

   24             }

   25         }

   26     }

Now all I need to do is hook this up with my controller method. In the Sign in method, I add the attribute [BindAndValidatiate] and all I need to do is check that the model state is valid. If so, I perform the log in.

    1     public class AccountController : BaseController {

    2         public ActionResult Signin() {

    3             return View();

    4         }

    5 

    6         [HttpPost]

    7         public ActionResult Signin([BindAndValidate] ChangeEmailModel model) {

    8 

    9             if (ModelState.IsValid)

   10                 PerformSignIn();

   11 

   12             return View();

   13         }

   14     }

Linking MVC View Models with Fluent Validation

Lets look at how all this works. What we need to do is create out model, then create our validator. We then hook our validator to our model by adding the validator atrribute to our model. I am using a simple Register View Model here as an example.

    1     [Validator(typeof(RegisterViewModelValidator))]

    2     public class RegisterViewModel

    3     {

    4         public string Email { get; set; }

    5         public string Password { get; set; }

    6         public string ConfirmPassword { get; set; }

    7     }

Now for the model validator. Here we have some simple rules. The password must not be empty, and it must also be a good password. The password confirmation must be the same as the password, and finally the Email must be a valid email address, and also not already exisit in our site.

    1     public class RegisterViewModelValidator : AbstractValidator<RegisterViewModel> {

    2         public RegisterViewModelValidator() {

    3             RuleFor(reg => reg.Password)

    4                     .NotEmpty()

    5                     .WithMessage("Please provide a password")

    6                     .Must(BeGoodPassword)

    7                     .WithMessage("Password must be at least 8 characters long, and contain numbers and letters");

    8 

    9             RuleFor(reg => reg.ConfirmPassword)

   10                     .Equal(reg => reg.Password)

   11                     .WithMessage("Passwords do not match");

   12 

   13             RuleFor(reg => reg.Email)

   14                    .EmailAddress()

   15                    .WithMessage("Invalid Email")

   16                    .Must(BeUniqueEmail)

   17                    .WithMessage("Account already Registered");

   18         }

   19 

   20         public bool BeGoodPassword(string password) {

   21             Regex regex = new Regex(@"^.*(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$");

   22             return regex.IsMatch(password);

   23         }

   24 

   25         public bool BeUniqueEmail(string email) {

   26             int count = Repository.GetInstance().CountOccurrencesOfEmail(email);

   27             return (count == 0);

   28         }

   29     }

Test your validation

Now, finally for the testing, whcih is really useful, when I want to make sure that things work 100%! To keep it simepl, I am just going to test the password rule, because testing the email requires a lot more of an explination. So working from some simple examples Here: I have written three tests. Thfirst is to make sure that the password can not be null. The second is to catch a week password. The third makes sure that a strong password does not cause an error.

    1         [Test]

    2         public void Should_have_error_when_Password_is_null() {

    3             validator.ShouldHaveValidationErrorFor(reg => reg.Password, null as string);

    4         }

    5 

    6         [Test]

    7         public void Should_have_error_when_Password_is_weak() {

    8             validator.ShouldHaveValidationErrorFor(reg => reg.Password, "weakpass");

    9         }

   10 

   11         [Test]

   12         public void Should_not_have_error_when_Password_is_strong() {

   13             Validator.ShouldNotHaveValidationErrorFor(reg => reg.Password, "SecretPassword123");

   14         }

And that is it! There is quite a lot you can achieve with fluent validation, such as reusing validators on complex properties and also some useful conditions like when or unless! The reasons I like this are that it uses generics to help build clean code. There is now no need to attributes on every property I have. Also, Jeremy was also very quick to help with any questions I had. Thanks for the help Jeremy.

Testing code changes, bugfixes, new features, …

When you implement a new feature somewhere, when you change just some bits of your code, when you fix a bug, or you just change a common text in an app… What do you do afterwards? Do you really check the result or do you trust yourself that it works fine 100%. It is an interesting thing to talk about… Continue reading ‘Testing code changes, bugfixes, new features, …’ »

Bulk testing your model attributes with rails

When it comes to testing in Ruby on Rails I tend to test every piece of its public interface. This means I test every single public method and attribute to ensure my desired functionality. Recently I’ve updated my application from Rails 1.2.5 to 2.0.1 and I was happy to have tests. None of them failed and so I knew that my application is ready to rock with the new Rails 2.0.
However, what I want to write in this article about is how to do bulk testing of each single attribute of your models. Let’s be a bit precise. Say we have a model User which has attributes firstname, lastnameand age. In order to perfectly test the User model we should write tests which …

  1. ensure that invalid values result in an error for the tested attribute (e.g. age -2 is invalid, so the instance should hold an error for the attribute age)
  2. and valid values don’t result in an error for the tested attribute (e.g. age 20 should be fine)

Usually you should test a couple of invalid values and a couple of valid values against each attribute of your model. This can be quite a lot to code. I explain a nice approach how to speed things up and save time for the next family event. Continue reading ‘Bulk testing your model attributes with rails’ »