Faking ModelState.IsValid–unit tests in Asp.Net Mvc
As a part of my thesis , I am creating web app in Asp.net MVC. I m using NHibernate , NUnit , RhinoMocks , WCF , Ninject , Glimpse and also Elmah . This is a quite big project with a lot of unit tests. I am treating it as a playground.
This is the the first post o of a series about using unit tests with MVC and WCF .
Create entity action scenario in my app is simple. First there is a get action which builds View and prepares model. Then this newly created model (filled with values from the view) is passed to action with [HttpPost] attribute. It is a good practice to if ModelState.IsValid before performing any DB operations.
I have a lot of tests testing controllers and their action. In this case on of the tests should check behaviour of the controller when the ModelState.IsValid value is false. I have tried different approaches : trying to mock controller , trying to mock its context , inspecting code with dotPeek (cool decompiler from the JetBrains) wasn’t helpfull. Then I realized that you can do something like this.
//Faking ModelState.IsValid = false
CourseController.ModelState.Add("testError", new ModelState());
CourseController.ModelState.AddModelError("testError", "test");
[Test]
public void Post_if_model_state_invalid_then_dont_add_course_and_return_error_view()
{
#region Arrange
//Faking ModelState.IsValid = false
CourseController.ModelState.Add("testError", new ModelState());
CourseController.ModelState.AddModelError("testError", "test");
using (Mock.Record())
{
Expect.Call(CourseService.AddCourse(Course)).Repeat.Never();
}
#endregion
#region Act
ViewResult view;
using (Mock.Playback())
{
view = (ViewResult)CourseController.Create(Course);
}
#endregion
#region Assert
Assert.That(view.ViewName,Is.EqualTo("Error"));
Assert.That(view.ViewBag.Error, Is.EqualTo(elearn.Common.ErrorMessages.Course.ModelUpdateError));
#endregion
}
As you can see , I am modifying ModelState by injecting fake data that will result in IsValid property set to false.