Looking at VS2013, I’m impressed with it’s speed over VS2012 not to mention that Microsoft appears to be releasing more often and taking into consideration a lot of community feedback. Other than the quickly visible improvements, I noticed that the virtual web server would stop working when debugging was stopped in Visual Studio. To fix this open you ASP.NET project properties and uncheck “Enable Edit and Continue”. Once this is unchecked IIS Express will run after debugging has stopped.
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.