title: Mocking HttpRequest and HttpResponse for MVC Application
body: <p>I'm currently writing some unit tests to check the functionality and correct workings of the ASP MVC application that we have written.
  In this MVC Application, I'm using a special ActionFilterAttribute that allows for authentication when making requests to the MVC Application.</p>
  
  <p>The code for this ActionFilterAttribute is this:</p>
  
  <pre><code>using System;
  using System.Security.Authentication;
  using System.Text;
  using System.Web.Mvc;
  using TenForce.Execution.Framework;
  using TenForce.Execution.Api2.Implementation;
  
  namespace TenForce.Execution.Web.Filters
  {
       /// &lt;summary&gt;
       /// This class defines a custom Authentication attribute that can be applied on      controllers.
       /// This results in authentication occurring on all actions that are beeing defined in the controller
       /// who implements this filter.
       /// &lt;/summary&gt;
       [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
       public class AuthenticationFilter : ActionFilterAttribute
       {
           #region IAuthorizationFilter Members
  
           /// &lt;summary&gt;
           /// This function get's called by the Mvc framework prior to performing any actions on
           /// the controller. The function will check if a call is authorized by the caller.
      /// The function will extract the username and password from the HTTP headers send by
      /// the caller and will validate these against the database to see if there is a valid
      /// account for the user.
      /// If the user can be found in the database, operations will resume, otherwise the action
      /// is canceled.
      /// &lt;/summary&gt;
      /// &lt;param name="filterContext"&gt;The context for the filter.&lt;/param&gt;
      public override void OnActionExecuting(ActionExecutingContext filterContext)
      {
          // Call the base operations first.
          base.OnActionExecuting(filterContext);
  
          // Surround the entire authentication process with a try-catch to prevent errors from
          // breaking the code.
          try
          {
              // Extract the custom authorization header from the HTTP headers.
              string customAuthHeader = Encoding.UTF8.GetString(Convert.FromBase64String(filterContext.RequestContext.HttpContext.Request.Headers["TenForce-Auth"]));
  
              // Split the header in the subcomponents.
              string[] components = customAuthHeader.Split('|');
  
              // Check if both components are present.
              if (components.Length &gt;= 2)
              {
                  // This header consists of 2 parts, the username and password, seperate by a vertical pipe.
                  string username = components[0] ?? string.Empty;
                  string password = components[1] ?? string.Empty;
                  string databaseId = Authenticator.ConstructDatabaseId(filterContext.HttpContext.Request.RawUrl);
  
                  // Validate the user against the database.
                  if (Authenticator.Authenticate(username, password, databaseId))
                  {
                      // The request is valid, so add the custom header to inform the request was
                      // authorized.
                      AllowRequest(filterContext);
                      return;
                  }
  
                  throw new InvalidCredentialException(@"The provided username &amp; password combination is invalid. Username : " + username);
              }
  
              // If we reach this point, the authorization request is no longer valid.
              throw new InvalidCredentialException(@"Insufficient parameters supplied for a valid authentication.");
          }
          catch (Exception ex)
          {
              // Log the exception that has occurred.
              Logger.Log(GetType(), ex);
  
              // Cancel the request, as we could not properly process it.
              CancelRequest(filterContext);
          }
      }
  
      #endregion
  
      #region Private Methods
  
      /// &lt;summary&gt;
      /// Cancels the Athorization and adds the custom tenforce header to the response to
      /// inform the caller that his call has been denied.
      /// &lt;/summary&gt;
      /// &lt;param name="authContext"&gt;The authorizationContxt that needs to be canceled.&lt;/param&gt;        
      private static void CancelRequest(ActionExecutingContext authContext)
      {
          authContext.Result = new HttpUnauthorizedResult();
          if (!authContext.RequestContext.HttpContext.Request.ServerVariables[@"SERVER_SOFTWARE"].Contains(@"Microsoft-IIS/7."))
              authContext.HttpContext.Response.AddHeader(@"Tenforce-RAuth", @"DENIED");
          else
              authContext.HttpContext.Response.Headers.Add(@"Tenforce-RAuth", @"DENIED");
      }
  
      /// &lt;summary&gt;
      /// Allows the Authorization and adds the custom tenforce header to the response to
      /// inform the claler that his call has been allowed.
      /// &lt;/summary&gt;
      /// &lt;param name="authContext"&gt;The authorizationContext that needs to be allowed.&lt;/param&gt;
      private static void AllowRequest(ActionExecutingContext authContext)
      {
          authContext.Result = null;
          if (!authContext.RequestContext.HttpContext.Request.ServerVariables[@"SERVER_SOFTWARE"].Contains(@"Microsoft-IIS/7."))
              authContext.HttpContext.Response.AddHeader(@"Tenforce-RAuth", @"OK");
          else
              authContext.HttpContext.Response.Headers.Add(@"Tenforce-RAuth", @"OK");
      }        
  
      #endregion
      }
  }
  </code></pre>
  
  <p>The problem I'm currently facing is that I can't seem to properly mock the section with the response headers. I've written a UnitTest that mocks a HttpRequest and HttpResponse object and calls the attribute function with the request. I can follow the successful login path branch in the code for an IIS7 simulation as this relies on properties, but when I try to follow the IIS6 branch in a login, I'm getting null pointer exceptions.</p>
  
  <p>I use the following code to construct the MoQ objects:</p>
  
  <pre><code>/// &lt;summary&gt;
      /// This function is called before running each test and configures the various properties
      /// of the test class so that each test will run with the same settings initialy.
      /// The function will configure the Mock Framework object so that they simulate a proper
      /// web request on the ActionFilter of a Controller.
      /// &lt;/summary&gt;
      [SetUp]
      protected void TestSetup()
      {
          // Construct the Mock object required for the test.
          HttpRequest = new Mock&lt;HttpRequestBase&gt;();
          HttpResponse = new Mock&lt;HttpResponseBase&gt;();
          HttpContext = new Mock&lt;HttpContextBase&gt;();
          ActionContext = new Mock&lt;ActionExecutingContext&gt;();
          Filter = new Web.Filters.AuthenticationFilter();
  
          // Configure the properties to modify the headers, request and response
          // objects starting from the HttpContext base object.
          // Also create the custom header collection and set the test URI.
          ActionContext.SetupGet(c =&gt; c.HttpContext).Returns(HttpContext.Object);
          HttpContext.SetupGet(r =&gt; r.Request).Returns(HttpRequest.Object);
          HttpContext.SetupGet(r =&gt; r.Response).Returns(HttpResponse.Object);
          HttpResponse.SetupGet(x =&gt; x.Headers).Returns(new System.Net.WebHeaderCollection());
          HttpRequest.SetupGet(r =&gt; r.RawUrl).Returns(@"http://test.tenforce.tst");
      }
  </code></pre>
  
  <p>The actuall test looks like this:</p>
  
  <pre><code>/// &lt;summary&gt;
      /// &lt;para&gt;This test will call the ActionFilter and perform a standard authorization request against the
      /// database using the credentials of the system administrator account. The test relies on the MoQ
      /// framework to mock several of the key components in the MVC Framework such as the HttpRequest, 
      /// HttpResponse and HttpContext objects.&lt;/para&gt;
      /// &lt;para&gt;The test expects the authentication to succeed, and relies on the IIS6 implementation.&lt;/para&gt;
      /// &lt;/summary&gt;
      [Test, MaxDuration]
      public void SuccessfullAuthenticationOnIis6()
      {
          // Configure the Authentication header of the request, so that a valid authentication
          // can take place. We want valid login credentials when the filter requests the header.
          HttpRequest.SetupGet(r =&gt; r.Headers).Returns(new System.Net.WebHeaderCollection { { @"TenForce-Auth", CorrectAuthToken } });
          HttpRequest.SetupGet(r =&gt; r.ServerVariables).Returns(
              new System.Collections.Specialized.NameValueCollection { { @"SERVER_SOFTWARE", @"Microsoft-IIS/6.0" } });
          HttpResponse.SetupGet(r =&gt; r.Headers).Returns(new System.Collections.Specialized.NameValueCollection());
          HttpResponse.Setup(r =&gt; r.AddHeader(@"TenForce-RAuth", @"OK"));
  
          // Call the action on the filter and check the response.
          Filter.OnActionExecuting(ActionContext.Object);
  
          // Check the ActionResult to null and that the response header contains the correct value.
          Assert.IsTrue(ActionContext.Object.Result == null);
          Assert.IsTrue(ActionContext.Object.HttpContext.Response.Headers["TenForce-RAuth"].Equals(@"OK"));
      }
  </code></pre>
  
  <p>The last assert is failing because the header is not beeing set. I've used the debugger to step through the code and the filter does actually set the header, so I think that the MoQ object is not properly configured to handle the request. </p>
  
  <p>Could someone please shed some light on how I can get my HttpResponse to accept the Headers.Add() request?</p>