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