Код ответа модуля MVC3

У меня есть контроллер в MVC3, который должен вернуть код ответа 500, если что-то пойдет не так. Я делаю это, возвращая объект вида и устанавливая код ответа http равным 500 (я проверил это в firebug, и все работает отлично).

public ActionResult http500()
{
    ControllerContext.HttpContext.Response.StatusCode = 500;
    ControllerContext.HttpContext.Response.StatusDescription = "An error occurred whilst processing your request.";

    return View();
}

Теперь у меня есть проблема: мне нужно написать unit test, который проверяет код ответа. Я попытался получить доступ к коду ответа несколькими разными способами как через объект ViewResult, так и контекст контроллера.

Ни один из способов не дает мне код ответа, который я установил в контроллере.

[TestMethod()]
public void http500Test()
{
   var controller = new ErrorController();
   controller.ControllerContext = new ControllerContext(FakeHttpObject(), new RouteData(), controller);


   ViewResult actual = controller.http500() as ViewResult;
   Assert.AreEqual(controller.ControllerContext.HttpContext.Response.StatusCode, 500);

}

Как бы я хотел получить код ответа 500 от контроллера или это больше связано с тестированием интеграции.

Ответ 1

Как сделать это более способом MVCish:

public ActionResult Http500()
{
    return new HttpStatusCodeResult(500, "An error occurred whilst processing your request.");
}

а затем:

// arrange
var sut = new HomeController();

// act
var actual = sut.Http500();

// assert
Assert.IsInstanceOfType(actual, typeof(HttpStatusCodeResult));
var httpResult = actual as HttpStatusCodeResult;
Assert.AreEqual(500, httpResult.StatusCode);
Assert.AreEqual("An error occurred whilst processing your request.", httpResult.StatusDescription);

или если вы настаиваете на использовании объекта Response, вы можете создать поддельный:

// arrange
var sut = new HomeController();
var request = new HttpRequest("", "http://example.com/", "");
var response = new HttpResponse(TextWriter.Null);
var httpContext = new HttpContextWrapper(new HttpContext(request, response));
sut.ControllerContext = new ControllerContext(httpContext, new RouteData(), sut);

// act
var actual = sut.Http500();

// assert
Assert.AreEqual(500, response.StatusCode);
Assert.AreEqual("An error occurred whilst processing your request.", response.StatusDescription);

Ответ 2

Что такое FakeHttpObject()? Это макет, созданный с использованием Moq? В этом случае вам нужно настроить сеттеры и геттеры для хранения фактических значений где-нибудь. Mock<T> не предоставляет никакой реализации свойств и методов. При установке значения свойства буквально ничего не происходит, и значение "потеряно".

Другой вариант - предоставить поддельный контекст, который является конкретным классом с реальными свойствами.