ASP.NET 3.5: improving testability with System.Web.Abstractions

The testability of ASP.NET code has long been a challenge; creating unit tests for your ASP.NET code has been difficult. One of the main points of the new ASP.NET MVC framework has been to make code written for it easily testable. However, not many people know that in ASP.NET 3.5, Microsoft has added a few features to make any ASP.NET applications, not only ASP.NET MVC applications, more easy to test. The System.Web.Abstractions assembly adds a few classes to the System.Web namespace that will help the situation. For instance, looking at the documentation for System.Web.HttpRequestBase, it states that

The HttpRequestBase class is an abstract class that contains the same members as the HttpRequest class. The HttpRequestBase class enables you to create derived classes that are like the HttpRequest class, but that you can customize and that work outside the ASP.NET pipeline. When you perform unit testing, you typically use a derived class to implement members that have customized behavior that fulfills the scenario that you are testing.

Very well. Looking at the documentation for HttpRequest, we see that HttpRequest is not a decendent of HttpRequestBase as one might expect from the name. The reason for this is probably that that would break backwards compatability with older versions of ASP.NET. So, how can we exploit the HttpRequestBase then? The answer is the HttpRequestWrapper class which is a decendant of HttpRequestBase and has a constructor that takes an HttpRequest object as a parameter. Then, we can take the HttpRequest object passed to our code from the framework, wrap it inside an HttpRequestWrapper object and pass it on to our code as a HttpRequestBase object. As I will show you in the examples below, this will enable us to create unit tests of our code by creating fake implementations of ASP.NET framework clases (using Rhino.Mocks).

Example #1: Testing a page codebehind file

Take, for instance, this simple page codebehind code that we would like to test:

using System;
using System.Web;

public partial class _Default : System.Web.UI.Page { protected void Page_Init(object sender, EventArgs e) { Response.Cache.SetCacheability(HttpCacheability.NoCache); } } The first step to take here, is to extract a method which take the request object as a parameter instead of fetching it from a method in a superclass. In general, this is a variation of the dependency injection pattern which in many situations will help us make our code testable (also, see my earlier related post). Like so:

using System.Web;
using System;

public partial class _Default : System.Web.UI.Page { protected void Page_Init(object sender, EventArgs e) { SetCacheablityOfResponse(Response); }

public void SetCacheablityOfResponse(HttpResponse response)
{
    response.Cache.SetCacheability(HttpCacheability.NoCache);
}

} So, then having extracted our code in a separate method, the next step is to change the parameter type of this method from HttpRequest to HttpRequestBase. Furthermore, when calling this method, we need to wrap the HttpRequest object by creating an instance of HttpRequestWrapper. The code, then, looks like this:

using System.Web;
using System;

public partial class _Default : System.Web.UI.Page { protected void Page_Init(object sender, EventArgs e) { SetCacheablityOfResponse(new HttpResponseWrapper(Response)); }

public void SetCacheablityOfResponse(HttpResponseBase response)
{
    response.Cache.SetCacheability(HttpCacheability.NoCache);
}

} Having now prepared our code for testing, we can create a unit test where we test the SetCacheabilityOfResponse method:

[TestMethod]
public void ShouldSetNoCacheabilityOnDefaultPage()
{
    _Default page = new _Default();
    MockRepository mocks = new MockRepository();
    HttpResponseBase responseStub = mocks.Stub<HttpResponseBase>();
    HttpCachePolicyBase cachePolicyMock = mocks.CreateMock<HttpCachePolicyBase>();
    With.Mocks(mocks).Expecting(delegate
    {
        SetupResult.For(responseStub.Cache).Return(cachePolicyMock);
        cachePolicyMock.SetCacheability(HttpCacheability.NoCache);
        LastCall.On(cachePolicyMock).Repeat.AtLeastOnce();
    }).Verify(delegate
    {
        page.SetCacheablityOfResponse(responseStub);
    });
}
If you are not familiar with Rhino.Mocks or any other mocking framework, there appears to be a lot going on in that test. The basic idea is that we create derivatives of the -Base classes and pass these to the code that we are going to test, mimicking the behavior of the “real” objects that the framework would pass our code at runtime. Also note that in this particular test we test the side effect of our code, namely that the code should call a the SetCacheability method with a specific parameter. This is achieved using a mock object.

Example #2: Testing an HTTP Handler

Given the following HTTP handler code:

using System;
using System.Web;

public class RedirectAuthenticatedUsersHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { if (context.Request.IsAuthenticated) { context.Server.TransferRequest("/farfaraway"); } } } Again, we extract the code we want to test into a separate method, passing it a -Base object and wrap the object passed to us from the framework in a -Wrapper object:

using System;
using System.Web;

public class RedirectAuthenticatedUsersHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { TransferUserIfAuthenticated(new HttpContextWrapper(context)); }

public void TransferUserIfAuthenticated(HttpContextBase context)
{
    if (context.Request.IsAuthenticated)
    {
        context.Server.TransferRequest("/farfaraway");
    }
}

} This allows us to create unit tests for the TransferUserIfAuthenticated method, for instance:

[TestMethod]
public void ShouldRedirectAuthenticatedUser()
{
    RedirectAuthenticatedUsersHandler handler = new RedirectAuthenticatedUsersHandler();
    MockRepository mocks = new MockRepository();
    HttpContextBase httpContextStub = mocks.Stub<HttpContextBase>();
    HttpRequestBase httpRequestBaseStub = mocks.Stub<HttpRequestBase>();
    HttpServerUtilityBase httpServerUtilityMock = mocks.CreateMock<HttpServerUtilityBase>();
    With.Mocks(mocks).Expecting(delegate
    {
        SetupResult.For(httpContextStub.Request).Return(httpRequestBaseStub);
        SetupResult.For(httpContextStub.Server).Return(httpServerUtilityMock);
        SetupResult.For(httpRequestBaseStub.IsAuthenticated).Return(true);
        httpServerUtilityMock.TransferRequest("/farfaraway");
        LastCall.On(httpServerUtilityMock).Repeat.AtLeastOnce();
    }).Verify(delegate
    {
        handler.TransferUserIfAuthenticated(httpContextStub);
    });
}

Summary

I have shown two very simple examples on how some of the classes in the System.Web.Abstractions assembly can help us test our ASP.NET code. I have used HttpResponseBase, HttpServerUtilityBase, HttpContextBase, HttpRequestBase, and HttpCachePolicyBase. Note that there are a number of classes available, so if you are faced with not being able to test your ASP.NET code because of dependencies to classes in the framework, take a look in the System.Web namespace and see if there are -Base classes that can help you out.

Testability is a large topic, and there is much to be said about it. I have shown a couple of very simple examples on how to improve testability. Testability has a lot to do with code design as well; in a real world I would write the test before writing the code and I would move my code out of codebehinds. Those topics are discussed a lot elsewere, hopefully this post will bring you a small step further in writing testable code.

Share

The mother lode for IIS, Kerberos and IWA information

I just came across Ken Schaefer’s blog, and I found that he has posted a series of excellent posts concerning various aspects of getting Integrated Windows Authentication / Kerberos to work on IIS:

Simply a great source of information!

Share

Solution for unit testing SharePoint does not fix root cause

21apps.com has written an article about how to use Typemock Isolator in order to unit test SharePoint applications. According to the article, Typemock has become the tool of choice for unit testing SharePoint as it supports faking everything including the sealed classes found throughout the object model”. Problem is that the root cause that prevents unit testing in SharePoint is an invasive API that creates dependencies between your code and the API. Using Typemock Isolator is treating the concequences without attacking the cause of the problem. But of course, having unit test is an advantage compared to having none.

Share

Pure functions and testability

When trying to introduce unit tests into an existing project, code dependencies is often a problem. During a teeth-grinding session grappling with this problem I came to think about pure functions.

Pure functions are functions that (according to Wikipedia‘s definition):

  • always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change as program execution proceeds, nor can it depend on any external input from I/O devices, and
  • evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.

Seems to me that pure functions would be a wet dream for unit testing. Imagine, you could pass in whatever the function needed to execute, and then check its return value. No mocking about with mock objects with side effect expectations needed!

But alas, we live in a world with non-pure functions. Even in functional programming, which does explicitly keep any state, you find them. In an object oriented language a primary idea is that objects should carry state. An object has a state. Period. However, if we can be inspired by the notion of pure functions, and make methods that have less dependencies, we will be much better off when it comes to unit testing.

I my experience, the ASP.NET programming model with ASPX code behind files is a model that promotes writing methods that are problematic to create unit tests for.

Take, for example, the following (theoretical, I admit) code behind snippet example:

protected void Page_Load(object sender, EventArgs e)
    {
        ShowOrHideEditButton(Page.User.Identity.Name);
    }
    void ShowOrHideEditButton(string currentUser)
    {
        if (Request.QueryString["user"].Equals(currentUser))
        {
            EditButton.Enabled = true;
        }
        else
        {
            EditButton.Enabled = false;
        }
    }
So, what is the problem here? Actually, there are two problems.

  1. The ShowOrHideMethod is not only dependant on its input parameters, but also on another member variable. When looking at the method signature, you do not see this, and might be misleaded about what the outcome of the methods is dependent on.
  2. The method does not return any value, but has a side-effect on its environment (setting the edit button visibility).

These two issues, makes it troublesome to test the method in a unit test. You have spend time to set up the methods context, and you have to measure the method’s side effects in order to make assesments about its result.

A much better approach would be something like this:

    protected void Page_Load(object sender, EventArgs e)
    {
        EditButton.Enabled = ShowOrHideEditButton(Page.User.Identity.Name, Request.QueryString["user"]);
    }
    bool ShowOrHideEditButton(string currentUserName, string profilePerson)
    {
        return (currentUserName.Equals(profilePerson));
    }
This way, we can easily test the ShowOrHideEditButton method in a unit test without having to use a great deal test code to set up the test context.

For increased testability, I would suggest the following for better method purity:

  • A method should evaluate the same result, given the same argument value(s) and object state.
  • A method execution result should be represented as, in order of preference: 1) a return value, 2) changed object state (mutation), or 3) a side-effect on an I/O device
Share

ASP.NET: Delegate identity from a web application to a back end web application

One of the things that seem very simple on a Powerpoint presentation, but are not that simple in practice, is having a web user’s identity forwarded from a calling web application to another web application when using Kerberos.

The case is as follows: I have an intranet application A which uses Integrated Windows Authentication to authenticate the user. During processing of a request from a web users, application A then makes an HTTP request to intranet application B. Application B requires the web user to be authenticated to process the request. The often most attractive solution for solving this is what Microsoft refers to as identity delegation. Simple in a Powerpoint presentation, but alas, not so simple in practice.

First of all, there are a number of preconditions in the computing environment configuration that need to be fulfilled. I found a very good summary of gotchas in this respect here. In my case, the points 2 and 6 was  missing (I knew about the other once beforehand). So, when all configuration stuff set up, then the only thing left is the code and configuration in the application A.

Basically, you need to make the application impersonate the web user (meaning that it will run with the credentials of the web user). There are two ways to do this. If you wish the entire request to run as the web user, you can insert an <identity impersonate=”true” /> element under <system.web> in the application’s web.config. Or, if you wish only the request to application B to run as the web user, you can do this programmatically:

using System.Security.Principal;
...
WindowsIdentity identity = (WindowsIdentity)HttpContext.Current.User.Identity();
using (identity.Impersonate())
{
    // ... code to call application B goes here ...
}
Then, the next task is to call application B itself. You can do this by creating a web request:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.somethingcompletelydifferent.com");
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
request.UseDefaultCredentials = true;
...
HttpWebResponse response = request.GetResponse();
...
The important things to notice here is that we set the ImpersonationLevel property to “Delegation” and that we set the UseDefaultCredentials property to “true”. So, it together, we get:
using System.Security.Principal;
...
WindowsIdentity identity = (WindowsIdentity)HttpContext.Current.User.Identity();
using (identity.Impersonate())
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.somethingcompletelydifferent.com");
    request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
    request.UseDefaultCredentials = true;
    ...
    HttpWebResponse response = request.GetResponse();
    ...
}
You can then test that it works in application B by checking the name in HttpContext.Current.User.Identity.Name.

Share

Spring.NET: programatically add objects to the existing (XML) application context

My experience is that Spring.NET configuration files tend to grow very large. As far as I can figure, there are two principal problems that arise from this:

  1. The configuration files get difficult to read and maintain
  2. It gets easier to introduce errors in the configuration because of its size

In general, I am in favour of keeping configuration files as small as possible. I often work with web applications that can (quite) easily be redeployed to the production environment, hence I always ask the question “will this value ever change between environments or deployments” when considering introducing a new configuration part.

Now, the Spring XML configuration usually serves two main purposes; to wire together the application, and to provide values that should be possible to change between deployments of the application or for different environments. The first purpose, I would argue does not necessarily need to be in the XML configuration. Rather, if this is done in code, we get the benefit that the compiler will tell us right away if there are typos or missing references. If this wiring is in the XML configuration file, such errors will not surface until the application starts.

So, the question that I had, was how Spring context wiring could be combined in code and in XML. I found one way of doing it, but it is only applicable to singleton objects.

Say, for instance that we have an object “something” that we wish to have configured in XML:

  <object id="something" type="SpringTest.Something, SpringTest" singleton="false"/>
Then, we have a class that we want to initialize in code:
class Foo
{
    public Foo() { }
    private Something _s;
    Something S
    {
        set { _s = value; }
        get { return _s; }
    }
}
Now, we see that Foo has a dependency on Something; it needs an instance of Something to be injected. We can use the Spring context to do this after we have created the instance of Foo:
IApplicationContext context = ContextRegistry.GetContext();
Foo f = new Foo();
context.ConfigureObject(f, "fooPrototype");
But Spring does not yet know that the Foo instance needs to be injected Something. Hence, we need to tell Spring that by creating what I would call a “prototype” or “template” object configuration:
<object id="fooPrototype" type="ContextTestProject.Foo, ContextTestProject">
   <property name="S" ref="something"></property>
</object>
The final step is then to register our newly created object in the Spring context:
XmlApplicationContext xmlContext = context as XmlApplicationContext;
xmlContext.ObjectFactory.RegisterSingleton("foo", f);
After this, the Foo instance is available for the application in the Spring context.

Share

.NET: Threading safety issue with Dictionary

Jakub, one of the project members on my current project pointed me to this blog entry explaining a threading issue with Directory<K,V> in .NET: Hashtable and Dictionary thread safety considerations. I know that I earlier have written code exactly like the one in the blog entry, so this was a bit of an eye-opener.

Share

What is “Oslo”?

On NDC a couple of days ago, I went to a session where David Chappell talked about Microsoft’s forthcoming “Oslo”. He went to great lengths to not reveal too much, as Microsoft is keeping everything very secret.  In fact, he spent more time explaining what “Oslo” is not than what it actually is.

Figuring actually what is intended to be is not easy. However, from the presentation, we know that “Oslo” is more of a “technology” or “platform” rather than a product. It will consists of the following parts:

  • The Repository. It is a storage space that has schemas that defines its data types. Actually what type of information it is supposed to or limited to, is not known. However, examples include things such as process definitions, workflow definitions, IT infrastructure information, and SLAs.
  • The Visual Editor. This is a general purpose tool that allows for editing of content in the repository. General purpose meaning that it can be used for different types of data. However, not all communication with the repository need to go through this tool. Special purpose applications or tools can connect and interact with the repository directly.
  • Extensions to Windows Workflow Foundation (WF). I am not sure exactly what kind of extensions we will see, but I can guess that it would mean extra activity components.
  • The process server. Basically, the WF does not define any host process for running workflow, and the way I figure, the process server implement such a process. It will contain a component called Lifecycle manager that can manage many process host instances (I guess for Load balancing, failover, etc.). The process server will also contain the ability to run BizTalk stuff. A question that comes to mind is whether the process server is “Biztalk for managed code” – built with the capabilities of WF and WCF? Time will show.

So what is the common denominator for all this? I am not sure. I can’t help it, but one word that keeps popping up in my mind is “governance”. Will this be “Microsoft’s tool for IT governance”?

Anyways, the time perspective of this is not known. When will this be available? All we know, is that Microsoft is planning to deliver this in three releases. Will it be in 2009?

Share

DataSets – thanks, but no thanks

For reasons previously unclear to me, I have not really felt comfortable with ADO.NET DataSets. With regards to topics like testability, object orientation, and encapsulation they always left a bitter taste in my mouth. Furthermore, I have not come across any really good use for them, which nourished my mistrust even more. (I am not saying that there aren’t any good uses, though). So, the other day I started to look deeper into the matter to try to find some more solid arguments.

The first clue I got from David Veeneman‘s article “ADO.NET for the Object-Oriented Programmer – Part One“, where he claims that “ADO.NET doesn’t work with object designs because it’s not supposed to work with objects!” and that the best way to use ADO.NET in an object-oriented design is not to use it. Basically, using ADO.NET “all the way” – including DataSets – will result in a data-driven application rather than an object-oriented application. But I want object-oriented…

In my application, I would like to have my data in business objects, and not in DataSets. Basic concept of encapsulation. I want to place data and operations on that data in my class, hiding the nitty-gritty details from the outside world. As Jeremy D. Miller points out, you cannot embed any real logic in a DataSet, and you have to be careful about duplication of logic. Another point he makes, which I think is very important, is that DataSets are clumsy to use inside an automated tests in terms of test setup. This is exactly the same as I have experienced. Easy testability is something you should look for in your application/library/technology/gizmo.

So, is there any time DataSet should be used? According to Scott Mitchell, (in his article ‘Why I Don’t Use DataSets in My ASP.NET Applications‘) Data sets should only be used in

  1. In a desktop, WinForms application
  2. For sending/receiving remote database information or for allowing communication between disparate platforms

Scott then goes on to conclude that he generally recommends using DataReaders in web applications rather than DataSets. As he points out, you might be tempted to use DataSets to cache data from the database, but argues that you’d probably be better off storing custom objects instead as it is more efficient, and removes the tight coupling to database tables.

Lo, the conclusion. If I were you, I would hesitate using DataSets for anything than small, data driven applications. Here’s why:

  • Results in a non-object oriented application, which in turn hurts lowers cohesion, tightens coupling, and hurts encapsulation
  • Testability suffers. DataSets are very awkward to test in unit tests. Forget about TDD.
  • Tight coupling between database design and the rest of the applications. Makes change cumbersome.
  • YAGNI – DataSets offer a lot of functionality that you probably don’t need. It boils down to design/develop-time efficiency vs. run-time efficiency (pointed out in More On Why I Don’t Use DataSets in My ASP.NET Applications (also by Scott Mitchell). Personally, I think that when the application grows larger, the design/develop-time efficiency is more or lest lost, and maintainability problems with DataSets set in.
Share

ADSI Edit does not support simple LDAP bind

Came as a surprise to me. I came to suspect this as I was unsuccessful in connecting with ADSI EDit, while successful using LDP. I got a confirmation in this post on Microsoft Technet.

I have been unsuccessful of finding any documentation on this, while the documentation does state that “ADAM ADSI Edit does not support Secure Sockets Layer (SSL) connections”. I would be OK if it also pointed out the limitation when it comes to binds…

Share