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