Testability with System.Web.Abstractions and no mock framework

May 28, 2009

...

As a follow-up to my previous post ASP.NET 3.5: improving testability with System.Web.Abstractions, I would like to show how the same testability can be achieved without using any mock framework like Rhino.Mocks. The C# 3.0 featuires ‘object initializers’ and ‘automatic properties’ makes our code sufficiently non-verbose to make it easy and readable.

So, given the same examples as in my previous post, here is what the test code will look like:

Example #1: Testing a page codebehind file

[TestMethod]
public void ShouldSetNoCacheabilityOnDefaultPage()
{
    _Default page = new _Default();
    HttpCachePolicyMock httpCachePolicyMock = new HttpCachePolicyMock();
    page.SetCacheablityOfResponse(new HttpResponseStub
    {
        TheCache = httpCachePolicyMock
    });
    httpCachePolicyMock.ShouldHaveSetCacheabilityTo(HttpCacheability.NoCache);
}
class HttpResponseStub : HttpResponseBase
{
    public override HttpCachePolicyBase Cache { get { return TheCache; } }
    public HttpCachePolicyBase TheCache { get; set; }
}
class HttpCachePolicyMock : HttpCachePolicyBase
{
    private HttpCacheability _cacheability;
    public override void SetCacheability(HttpCacheability cacheability)
    {
        _cacheability = cacheability;
    }
    public void ShouldHaveSetCacheabilityTo(HttpCacheability expectedCacheability)
    {
        Assert.AreEqual(expectedCacheability, _cacheability);
    }
}

I have created two helper classes, one with the suffix -Stub and one with the suffix -Mock. The convention here is that a stub is a type of class used to provide a context to the class under test. Mocks also do that, but additionally a mock can make expectation about what should happen to it during the test.

Example #2: Testing an HTTP handler

[TestMethod]
public void ShouldRedirectAuthenticatedUser()
{
    HttpServerUtilityMock httpServerUtilityMock = new HttpServerUtilityMock();
    HttpContextStub httpContextStub = new HttpContextStub
    {
        TheRequest = new HttpRequestStub { IsItAuthenticated = true },
        TheServer = httpServerUtilityMock
    };
    new RedirectAuthenticatedUsersHandler().TransferUserIfAuthenticated(httpContextStub);
    httpServerUtilityMock.ShouldHaveTransferredTo("/farfaraway");
}
class HttpContextStub : HttpContextBase
{
    public override HttpRequestBase Request { get { return TheRequest; } }
    public override HttpServerUtilityBase Server { get { return TheServer; } }
    public HttpRequestBase TheRequest { get; set; }
    public HttpServerUtilityBase TheServer { get; set; }
}
class HttpRequestStub : HttpRequestBase
{
    public override bool IsAuthenticated { get { return IsItAuthenticated; } }
    public bool IsItAuthenticated { get; set; }
}
class HttpServerUtilityMock : HttpServerUtilityBase
{
    private string _path;
    public override void TransferRequest(string path)
    {
        _path = path;
    }
    public void ShouldHaveTransferredTo(string expectedPath)
    {
        Assert.AreEqual(expectedPath, _path);
    }
}

Profile picture

Written by Vidar Kongsli who is a software professional living in Oslo, Norway. Works as a consultant, system architect and developer at Bredvid. You should follow him on Twitter