Mocking ASP.NET MVC HttpConext and Sessions

Unit testing ASP.NET MVC controllers can be difficult when you start to use the HttpContext and Session state.  The following snippet of code will allow you to mock, using the Moq framework, the HttpContext properties.  Add this to your test project.

using System.Collections.Generic;
using System.Web;
using Moq;
using System.Collections.Specialized;
using System.Web.Routing;
using System.Web.Mvc;

namespace WebBackOffice.Tests
{
public class ContextMocks
{
public Mock<HttpContextBase> HttpContext { get; private set; }
public Mock<HttpRequestBase> Request { get; private set; }
public Mock<HttpResponseBase> Response { get; private set; }
public RouteData RouteData { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="ContextMocks"/> class.
/// </summary>
/// <param name="controller">The controller to add mock context to.</param>
public ContextMocks(Controller controller)
{
// define all the common context objects, plus relationsips between them
HttpContext = new Mock<HttpContextBase>();
Request = new Mock<HttpRequestBase>();
Response = new Mock<HttpResponseBase>();
RouteData = new RouteData();

HttpContext.Setup(m => m.Request).Returns(Request.Object);
HttpContext.Setup(m => m.Response).Returns(Response.Object);
HttpContext.Setup(m => m.Session).Returns(new FakeSessionState());

Request.Setup(m => m.Cookies).Returns(new HttpCookieCollection());
Request.Setup(m => m.QueryString).Returns(new NameValueCollection());
Request.Setup(m => m.Form).Returns(new NameValueCollection());

Response.Setup(m => m.Cookies).Returns(new HttpCookieCollection());

// apply the mock context to the supplied controller instance
RequestContext rc = new RequestContext(HttpContext.Object, new RouteData());
controller.ControllerContext = new ControllerContext(rc, controller);
}

/// <summary>
/// Sets the ajax request header so that mocked HttpRequest shows as a ajax call.
/// </summary>
public void SetAjaxRequestHeader()
{
Request.Setup(f => f["X-Requested-With"])
.Returns("XMLHttpRequest");
}

private class FakeSessionState : HttpSessionStateBase
{
Dictionary<string, object> _items = new Dictionary<string, object>();

public override object this[string name]
{
get
{
return _items.ContainsKey(name) ? _items[name] : null;
}
set
{
_items[name] = value;
}
}
}
}
}

Below is an example of using this in a unit test, based on nunit test framework.  During the setup, create the ContextMock and associated with the controller under test.

namespace MySite.Tests
{
public class AccountControllerTests
{
private MyAccountController myAccountController;
private ContextMocks contextMock;
private Mock<IAccountService> accountServiceMock;

[SetUp]
public void Setup()
{
// create new controller under test
myAccountController = new MyAccountController();

// create mock HttpContext
contextMock = new ContextMocks(myAccountController);

accountServiceMock = new Mock<IAccountService>();
myAccountController.AccountService = accountServiceMock.Object;
}

[TearDown]
public void Cleanup()
{
myAccountController = null;
contextMock = null;
accountServiceMock = null;
}

[Test]
public void SignUp_AjaxRequest_Returns_JsonResult()
{
// arrange
string email = "test@test.com";
string password = "Some#rei!23";

// configure ajax mock request
contextMock.SetAjaxRequestHeader();

accountServiceMock.Setup(f => f.CreateAccount(It.IsAny<string>(), It.IsAny<string>()))
.Returns(new SignUpResponse(SignUpResponse.ReturnCodeType.Success));

// act
ActionResult actual = myAccountController.SignUp(email, password);

// assert
Assert.IsInstanceOf<JsonResult>(actual);
}
}
}

Fixing 'mscorlib.dll' targets a different processor When Building x86

Currently I’m working on a product that has been around for a long time, and will be for a lot longer.  Even thought 64bit has been out for a long time, this application has it roots in 32bit.  This is not necessarily a bad thing, as 64bit will not provide any real processing performance enhancements.  Prior to Visual Studio 2010, building with AnyCPU platform configuration was straight forward.  Now that we support purely 64bit OS on our server side, things because a little more difficult.  Long story short, we needed to configure everything to specify x86.  In doing so, we continued to get build errors on our TFS team build server.  The error “error CS1607: Assembly generation -- Referenced assembly 'mscorlib.dll' targets a different processor” would show up all over the place.  After ensuring that all our projects were set to x86 and the Configuration Manager for debug/release specified x86, we eventually found that the build process MSBuild Platform needed to be set to X86.

As an interesting note, in our researching over x86 and x64, we came across this article AnyCPU Exes are usually more trouble than they're worth.  If you’ve been adding new projects in Visual Studio 2010, you’ll notice that they all default to x86. 

Office Communicator Is Cool Check This Out

So being a somewhat Microsoft shop, we use Office Communicator which is a pretty dandy little piece of software for inter company screen sharing and instant messaging.  The other day a colleague had a theory that we could create an infinite loop with Office Communicator by doing  a three way share.  Well it worked and was quite humorous, here is our result.

image

Alter Visual Studio Template Files

Out of the box, I’ve found Visual Studio template files to be just fine.  Recently I was doing some researching into using StyleCop so I installed in on my machine.  Little did I know, it went behind the scenes and altered some if now all template files.  In particular, I don’t care for their Interface and Class file templates, I tend to use ReSharper and GhostDoc to do cleanup and documentation.  If you want to change or revert your templates, your in luck, Visual Studio has backups.  Follow the steps below to restore whatever templates you need to.  In the example I will be restoring the C# class file for Visual Studio 2010 (10.0).

1.  Go to the template folder you desire.  You will find the templates in the Program Files folder (Program Files (x86) on 64 bit system) and the particular version  here C:\Program Files\Microsoft Visual Studio {Version of VS, 10.0, 9.0…}\Common7\IDE\ItemTemplates.  In the case of the C# class you will have to drill down into \CSharp\Code\1033\ folder, and in there you will find a file called Class.zip.bak.  Delete the existing Class.zip file, copy the Class.zip.bak and rename it to Class.zip.  Do this process for any other templates you wish to revert.

2.  Reset the IDE environment.  Open a Visual Studio command prompt (I do it in administrator mode on Windows 7).  It’s found in All Programs^Microsoft Visual Studio {Version 2010, 2008,…}^Visual Studio Tools.  Once the command windows is open run “devenv /setup” and you’re all set!