Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.net MVC - FluentValidation Unit Tests

I am using FluentValidation in my MVC project and have the following model and validator:

[Validator(typeof(CreateNoteModelValidator))]
public class CreateNoteModel {
    public string NoteText { get; set; }
}

public class CreateNoteModelValidator : AbstractValidator<CreateNoteModel> {
    public CreateNoteModelValidator() {
        RuleFor(m => m.NoteText).NotEmpty();
    }
}

I have a controller action to create the note:

public ActionResult Create(CreateNoteModel model) {
    if( !ModelState.IsValid ) {
        return PartialView("Test", model);

    // save note here
    return Json(new { success = true }));
}

I wrote a unit test to validate the behavior:

[Test]
public void Test_Create_With_Validation_Error() {
    // Arrange
    NotesController controller = new NotesController();
    CreateNoteModel model = new CreateNoteModel();

    // Act
    ActionResult result = controller.Create(model);

    // Assert
    Assert.IsInstanceOfType(result, typeof(PartialViewResult));
}

My unit test is failing because it doesn't have any validation errors. This should succeed because model.NoteText is null and there is a validation rule for this.

It appears that FluentValidation isn't running when I run my controller test.

I tried adding the following to my test:

[TestInitialize]
public void TestInitialize() {
    FluentValidation.Mvc.FluentValidationModelValidatorProvider.Configure();
}

I have this same line in my Global.asax to tie up the validators to the controllers automatically...but it doesn't appear to be working in my unit test.

How do I get this working correctly?

like image 701
Dismissile Avatar asked Oct 06 '11 20:10

Dismissile


1 Answers

That's normal. Validation should be tested separately from controller actions, like this.

And to test your controller action simply simulate a ModelState error:

[Test]
public void Test_Create_With_Validation_Error() {
    // Arrange
    NotesController controller = new NotesController();
    controller.ModelState.AddModelError("NoteText", "NoteText cannot be null");
    CreateNoteModel model = new CreateNoteModel();

    // Act
    ActionResult result = controller.Create(model);

    // Assert
    Assert.IsInstanceOfType(result, typeof(PartialViewResult));
}

A controller shouldn't really know anything about fluent validation. What you need to test here is that if there is a validation error in the ModelState your controller action behaves correctly. How this error was added to the ModelState is a different concern that should be tested separately.

like image 152
Darin Dimitrov Avatar answered Sep 30 '22 01:09

Darin Dimitrov