2012-03-26 2 views
11

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

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

    return View(); 
} 

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

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

[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 от контроллера или это скорее интеграционное тестирование.

ответ

33

Как делать это в более 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

Мне нравится этот подход, быстрый вопрос, хотя, если действие контроллера возвращает как код состояния, так и представление с моделью, есть ли ощущение гибкий способ имитировать как ответ кода состояния, так и результат представления/модели? Я изо всех сил пытаюсь придумать разумный вариант. – dougajmcdonald

+0

хороший вопрос @dougajmcdonald. вы получили ответ? – richardwhatever

0

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

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

Смежные вопросы