Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP MVC 3 testing controller calling ModelState.IsValid always returns true

I have an ASP MVC 3 application and in my Model I have implemented IValidatableObject.

When my controller posts for a create or edit, I obviously only want to save the model if it is valid.

I see many blogs and posts and answers that say something like

if(!ModelState.IsValid)
{
      return View();
}

My question. Why is it that ModelState.IsValid is always true in a unit test on the Controller?

Example:

[Test]
public void InValidModelsAreNotAdded()
{
    var invalidModel = new MyModel() { SomeField = "some data", SomeOtherField = "" };

    var result = _controller.Submit(invalidModel);

    _repository.AssertWasNotCalled(r => r.Add(Arg.Is.Anything));

}

Model code:


public class MyModel : IValidatableObject
{
    public string SomeField { get; set; }
    public string SomeOtherField { get; set; }

    public IEnumerable Validate(ValidationContext validationContext)
    {
        if(string.IsNullOrWhiteSpace(SomeOtherField))
        {
            yield return
                new ValidationResult("Oops invalid.", new[] {"SomeOtherField"});
        }
     }
}

The AssertWasNotCalled always fails this test.

I stepped through the test and noticed that the ModelState.IsValid is true for this test. It is as if the IValidatableObject.Validate is not being invoked. It seems to work when I run the project, but thats not much of a way to test drive an application.

Also, I realize I could use the [Required] attribute for my example, but my real code has much more complex validation to it.

Thoughts?

like image 753
Adam Avatar asked Feb 21 '11 15:02

Adam


1 Answers

It's true because you haven't called anything which sets it false.

This normally happens during binding, but since you just pass the model directly in the test you skip that altogether.

If you're trying to test validation, do that directly. If you're trying to test the error path in your controller, your test's arrange can call _controller.ModelState.AddModelError( //...

like image 138
Craig Stuntz Avatar answered Oct 26 '22 06:10

Craig Stuntz