ediblecode
ediblecode

Reputation: 11971

Testing the result of HttpResponse.StatusCode

I've written an ErrorsController that as you can imagine, has pretty simple methods to continue to serve dynamic content in the case of an error, e.g. 500.

Now what I want to do is test that in that method, HttpResponseBase.StatusCode is set to a given number while executing this method, but for some reason, the StatusCode property is always 0. This includes when examining the property directly after setting it.

Controller

public ViewResult NotFound()
{
    Response.StatusCode = (int)HttpStatusCode.NotFound;

    const string PageTitle = "404 Page Not Found";
    var viewModel = this.GetViewModel(PageTitle);

    return this.View(viewModel);
}

GetViewModel does nothing other than setting properties on a view model

Test

[SetUp]
public void Setup()
{
    this.httpContext = new Mock<HttpContextBase>();
    this.httpResponse = new Mock<HttpResponseBase>();

    this.httpContext.SetupGet(x => x.Response).Returns(this.httpResponse.Object);

    this.requestContext = new RequestContext(this.httpContext.Object, new RouteData());
    this.controller = new ErrorsController(this.contentRepository.Object);

    this.controllerContext = new Mock<ControllerContext>(this.requestContext, this.controller);
    this.controllerContext.SetupGet(x => x.HttpContext.Response).Returns(this.httpResponse.Object);
    this.controller.ControllerContext = this.controllerContext.Object;
}

[Test]
public void Should_ReturnCorrectStatusCode_ForNotFoundAction()
{
    this.controller.NotFound();
    this.httpResponse.VerifySet(x => x.StatusCode = (int)HttpStatusCode.NotFound); 
    Assert.AreEqual((int)HttpStatusCode.NotFound, this.httpResponse.StatusCode); 
}

Where am I going wrong here?

Upvotes: 2

Views: 11110

Answers (2)

Artur Karbone
Artur Karbone

Reputation: 1658

I end up with an extension method for mocking HttpContext

public static class HttpContextExtensions
{
    public static void MockHttpContext(this Controller controller)
    {
        var httpContextMock = new Mock<HttpContextBase>();
        var requestMock = new Mock<HttpRequestBase>();
        var responseMock = new Mock<HttpResponseBase>();

        responseMock.SetupAllProperties();
        requestMock.SetupAllProperties();

        httpContextMock.Setup(x => x.Response).Returns(responseMock.Object);
        httpContextMock.Setup(x => x.Request).Returns(requestMock.Object);

        controller.ControllerContext = new ControllerContext();
        controller.ControllerContext.HttpContext = httpContextMock.Object;
    }
}

Usage:

someController.MockHttpContext()

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038890

Just add this in your setup phase:

httpResponse.SetupAllProperties();

This being said, you probably don't need those 2 assertions:

this.httpResponse.VerifySet(x => x.StatusCode = (int)HttpStatusCode.NotFound); 
Assert.AreEqual((int)HttpStatusCode.NotFound, this.httpResponse.StatusCode); 

The first should be more than enough for your unit test.

Upvotes: 9

Related Questions