如何使用Response.StatusCode对控制器进行单元测试

时间:2014-02-20 13:38:33

标签: asp.net-mvc unit-testing asp.net-mvc-5

我在MVC5控制器上有一个方法: -

[HttpPost]
public JsonResult Save(TaskViewModel model)
{
    if (ModelState.IsValid)
    {
        var task = model.ToTask();
        _taskService.Save(task);
        return Json(task);
    }

    return Json(new ErrorViewModel(ModelState));
}

我很乐意进行单元测试: -

[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);
    }
}

但是,我需要使此方法返回400状态代码并返回内容。所以我对控制器方法做了以下更改。

[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));
}

这导致我的单元测试因{1}而失败,因为响应不存在。

所以我的问题是这里最好的做法是使这个控制器可测试并验证状态代码值吗?

更新 虽然这与MVC3 unit testing response code非常相似,但它没有解决我试图返回JSON内容以及400状态代码的问题

1 个答案:

答案 0 :(得分:0)

看看this answer。它详细解释了如何使用HttpContext和Response进行测试。