2012-03-26 18 views
11

Posiadam kontroler w ramach MVC3, który musi zwrócić kod odpowiedzi 500, jeśli coś pójdzie nie tak. Robię to, zwracając obiekt widoku i ustawiając kod odpowiedzi http równy 500 (sprawdziłem to w firebug i wszystko działa świetnie).Kod odpowiedzi jednostki testowej MVC3

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

    return View(); 
} 

Problem jaki mam teraz, to móc napisać test jednostkowy, który sprawdza kod odpowiedzi. Próbowałem uzyskać dostęp do kodu odpowiedzi na kilka różnych sposobów, zarówno poprzez obiekt ViewResult, jak i kontekst kontrolera.

W żaden sposób nie otrzymałem kodu odpowiedzi, który ustawiłem w kontrolerze.

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

} 

W jaki sposób chciałbym uzyskać kod odpowiedzi 500 od kontrolera lub jest to więcej rzeczy do testowania integracji.

Odpowiedz

33

Jak czyniąc go bardziej MVCish sposób:

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

, a następnie:

// 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); 

lub jeśli nalegać na użyciu obiektu Response można stworzyć fałszywy:

// 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

Podoba mi się to podejście, ale szybkie pytanie, czy działanie kontrolera zwraca zarówno kod statusu, jak i widok z modelem, czy jest jakiś sens sposób naśladowania zarówno odpowiedzi na kod statusu, jak i wyniku widoku/modelu? Staram się wymyślić rozsądną opcję. – dougajmcdonald

+0

dobre pytanie @ dougajmcdonald. dostałeś odpowiedź? – richardwhatever

0

Co to jest FakeHttpObject()? Czy to jest sztuczka stworzona za pomocą Moq? W takim przypadku musisz ustawić setery i moduły pobierające, aby przechowywać rzeczywiste wartości gdzieś. Mock<T> nie zapewnia żadnych implementacji właściwości i metod. Podczas ustawiania wartości właściwości dosłownie nic się nie dzieje, a wartość jest "stracona".

Inną opcją jest zapewnienie fałszywego kontekstu, który jest konkretną klasą z prawdziwymi właściwościami.

Powiązane problemy