I have a method on MVC5 controller:-
[HttpPost]
public JsonResult Save(TaskViewModel model)
{
if (ModelState.IsValid)
{
var task = model.ToTask();
_taskService.Save(task);
return Json(task);
}
return Json(new ErrorViewModel(ModelState));
}
Which I am happily unit testing like so:-
[Test]
public void Save_WhenInvalidModel_ThenDoNotCallITaskServiceSave()
{
var model = new TaskViewModel();
var service = new Mock<ITaskService>();
service.Setup(m => m.Save(It.IsAny<Task>()));
var controller = CreateController(service.Object);
ValidateModel(model, controller);
controller.Save(model);
service.Verify(f => f.Save(It.IsAny<Task>()), Times.Never());
}
protected static void ValidateModel(object model, Controller controller)
{
var validationContext = new ValidationContext(model, null, null);
var validationResults = new List<ValidationResult>();
Validator.TryValidateObject(model, validationContext, validationResults);
foreach (var validationResult in validationResults)
{
controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
}
However, I need to make this method return a 400 status code and return content. So I made the following change to the controller method.
[HttpPost]
public JsonResult Save(TaskViewModel model)
{
if (ModelState.IsValid)
{
var task = model.ToTask();
_taskService.Save(task);
return Json(task);
}
Response.StatusCode = 400;
Response.TrySkipIisCustomErrors = true;
return Json(new ErrorViewModel(ModelState));
}
This causes my unit test to fail with a System.NullReferenceException because Response does not exist.
So my question is what is the best practice here to both make this controller testable and also to verify the status code value?
UPDATE While this is very similar to MVC3 unit testing response code it does not address that I am trying to return JSON content as well as a 400 status code