Mehfuz's WebLog

Live crazy, think different!

Sponsors

News

Passionate about cutting edge technologies and facinated by the modern web and phone revolution.Currently working at Telerik Corporation, the leading .net component vendor.
Follow me


Articles


Projects

Playing with aspx page cycle using JustMock

In this post , I will cover a test code that will mock the various elements needed to complete a HTTP page request and  assert the expected page cycle steps. To begin, i have a simple enumeration that has my predefined page steps:

  1. public enum PageStep
  2. {
  3.     PreInit,
  4.     Load,
  5.     PreRender,
  6.     UnLoad
  7. }

Once doing so, i  first created the page object [not mocking].

  1. Page page = new Page();

Here, our target is to fire up the page process through ProcessRequest call, now if we take a look inside the method with reflector.net,  the call trace will go like : ProcessRequest –> ProcessRequestWithNoAssert –> SetInstrinsics –> Finallly ProcessRequest. Inside SetInstrinsics ,  it requires calls from HttpRequest, HttpResponse and HttpBrowserCababilities. Using this clue at hand, we can easily know the classes / calls  we need to mock in order to get through the expected call.

Accordingly, for  HttpBrowserCapabilities our required mock code will look like:

  1. var browser = Mock.Create<HttpBrowserCapabilities>();
  2. // Arrange
  3. Mock.Arrange(() => browser.PreferredRenderingMime).Returns("text/html");
  4. Mock.Arrange(() => browser.PreferredResponseEncoding).Returns("UTF-8");
  5. Mock.Arrange(() => browser.PreferredRequestEncoding).Returns("UTF-8");

Now, HttpBrowserCapabilities is get through [Instance]HttpRequest.Browser. Therefore, we create the HttpRequest mock:

  1. var request = Mock.Create<HttpRequest>();

Then , add the required get call :

  1. Mock.Arrange(() => request.Browser).Returns(browser);

As, [instance]Browser.PerferrredResponseEncoding and [instance]Browser.PreferredResponseEncoding  are also set to the request object and to make that they are set properly, we can add the following lines as well [not required though].

  1. bool requestContentEncodingSet = false;
  2. Mock.ArrangeSet(() => request.ContentEncoding = Encoding.GetEncoding("UTF-8")).DoInstead(() =>  requestContentEncodingSet = true);

Similarly, for response we can write:

  1.  var response = Mock.Create<HttpResponse>();
  2.  
  3.  bool responseContentEncodingSet = false;
  4.  Mock.ArrangeSet(() => response.ContentEncoding = Encoding.GetEncoding("UTF-8")).DoInstead(() => responseContentEncodingSet = true);

Finally , I created a mock of HttpContext and set the Request and Response properties that will returns the mocked version.

  1. var context = Mock.Create<HttpContext>();
  2.  
  3. Mock.Arrange(() => context.Request).Returns(request);
  4. Mock.Arrange(() => context.Response).Returns(response);

As, Page internally calls RenderControl method , we just need to replace that with our one and optionally we can check if  invoked properly:

  1. bool rendered = false;
  2. Mock.Arrange(() => page.RenderControl(Arg.Any<HtmlTextWriter>())).DoInstead(() => rendered = true);

That’s  it, the rest of the code is simple,  where  i asserted the page cycle with the PageSteps that i defined earlier:

  1. var pageSteps = new Queue<PageStep>();
  2.  
  3. page.PreInit +=delegate { pageSteps.Enqueue(PageStep.PreInit); };
  4. page.Load += delegate { pageSteps.Enqueue(PageStep.Load); };
  5. page.PreRender += delegate { pageSteps.Enqueue(PageStep.PreRender);};
  6. page.Unload +=delegate { pageSteps.Enqueue(PageStep.UnLoad);};
  7.  
  8. page.ProcessRequest(context);
  9.  
  10. Assert.True(requestContentEncodingSet);
  11. Assert.True(responseContentEncodingSet);
  12. Assert.True(rendered);
  13.  
  14. Assert.Equal(pageSteps.Dequeue(), PageStep.PreInit);
  15. Assert.Equal(pageSteps.Dequeue(), PageStep.Load);
  16. Assert.Equal(pageSteps.Dequeue(), PageStep.PreRender);
  17. Assert.Equal(pageSteps.Dequeue(), PageStep.UnLoad);
  18.  
  19. Mock.Assert(request);
  20. Mock.Assert(response);

You can get the test class shown in this post here to give a try by yourself with of course JustMock :-).

Enjoy!!

Posted: Apr 29 2010, 11:23 PM by mehfuzh | with 2 comment(s) |
Filed under: , , ,

Comments

ulu said:

I'm impressed with JustMock's capabilities as well as nice and clear syntax. While I understand that this is just an example created to demonstrate the power of JustMock, this example, IMO, is a perfect illustration of why mocking can be so painful, even with the best tools.

I summarized my thoughts in a blog post here: dotfresh.blogspot.com/.../testing-aspnet-pages-with-teleriks.html, and I also provided an example of how simple is testing the same using an integration test and the Ivonna library.

# July 5, 2010 3:39 PM

mehfuzh said:

Yes, you are right. The purpose of this article is to show the capabilities of JustMock. In ideal case , i myself will never prefer such mocking that includes 3rd party library calls directy into your code. But rather, use some proxy or adapter to do it for me. But in codebase that is old and testers have little control over how its implemented, sometimes this kind of features can just save your day.

But again, if you have the chance, write adapter or proxy and dont try this unless you need it.

By the way JustMock can run without the JM profiler.Personally,  when i will be using it in some of my OS projects, i do have the option to  turn it off to avoid any elevated options that can spoil me.

Regards,

Mehfuz

# July 6, 2010 2:23 AM