ASP.NET MVC 3: Using HttpNotFoundResult in controller tests

Lately I blogged about HttpNotFoundResult and HttpStatusCodeResult action results that come with ASP.NET MVC 3. These results are ideal for controller tests as we don’t have to mess with HttpContext and Response objects anymore. In this posting I will show you how to use HttpNotFoundResult in controller tests to check if errors are given correctly to user.

Let’s suppose we have controller method that displays product details.


public ActionResult Details(int productId)
{
    var product = _repository.GetProductById(productId);

    if (product == null)
    {
        var result = new HttpNotFoundResult("Product not found");
        return result;
    }
           
    // ...

    return View();
}

If product is not found (whatever the reason is) then Details() returns HttpNotFoundResult to let user know that requested product doesn’t exist. If product is there then Details() makes some processing and returns regular view that displays product information.

Now let’s write test to make sure that in the case of missing product error 404 will be returned.


[TestMethod]
public void ProductPageShouldReturn404IfProductNotFound()
{
    var productId = 1;
    Product product = null;

    var repositoryMock = new Mock<IProductRepository>();
    repositoryMock.Setup(c => c.GetProductById(productId))
                    .Returns(product)
                    .Verifiable();

    var result = _controller.Details(productId);

    repositoryMock.Verify();
    Assert.IsNotNull(result);
    Assert.IsInstanceOfType(result, typeof(HttpNotFoundResult));
}

This test makes sure that GetProductById() method is called from product repository mock and also it makes sure that this method returns null. After calling Details() method from controller we check three things:

  1. is GetProductById() method called?
  2. is return value not null?
  3. is return value of type HttpNotFoundResult?

If all these conditions are met then test succeeds. Our tests as you can see, is pretty short and all it does is checking returned type. We don’t have here any dealing with HttpContext and Response and that saves us a lot of trouble. At least in more complex tests.

Conclusion

HttpNotFoundResult and HttpStatusCodeResult are very good choices if we want our ASP.NET MVC applications to be more easily testable. This way we can avoid HttpContext and other related objects. If you want to customize HttpStatusCodeResult then please read my blog posting ASP.NET MVC 3: Creating HttpStatusCodeResult with view based body.

No Comments