I am attempting to create integration tests to make sure my views do not have any runtime errors in them. Thus I need to create a test that checks if ViewResult.ExecuteResult()
works correctly but it seems I have hit a snag.
I found this site which gave me a starting point, and I have the following code:
[TestMethod]
public void RegisterResultExecutes()
{
//arrange
RequestContext requestContext = new RequestContext(new MockHttpContext(), new RouteData());
AccountController controller = new AccountController
{
FormsService = new MockFormsAuthenticationService(),
MembershipService = new MockMembershipService(),
Url = new UrlHelper(requestContext)
};
var result = controller.Register();
var sb = new StringBuilder();
Mock<HttpResponseBase> response = new Mock<HttpResponseBase>();
response.Setup(x => x.Write(It.IsAny<string>())).Callback<string>(y =>
{
sb.Append(y);
});
Mock<ControllerContext> controllerContext = new Mock<ControllerContext>();
controllerContext.Setup(x => x.HttpContext.Response).Returns(response.Object);
//act
result.ExecuteResult(controllerContext.Object);
}
The problem is that when result.ExecuteResult()
is called I get the following exception
System.NullReferenceException: Object reference not set to an instance of an object.
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
MyApp.Tests.Controllers.AccountControllerTest.RegisterResultExecutes() in C:\Users\KallDrexx\Documents\Projects\MyApp\MyApp.Tests\Controllers\AccountControllerTests.cs: line 297
Unfortunately, that stack trace isn't very useful as I'm not sure what it's trying to access that is null. Does anyone have any suggestions on how I can create a test for ExecuteResult()
?
Based on the stack trace, it is something in the ViewResultBase.ExecuteResult
method that throws the exception. Using reflector, here is the definition of that method:
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (string.IsNullOrEmpty(this.ViewName))
{
this.ViewName = context.RouteData.GetRequiredString("action");
}
ViewEngineResult result = null;
if (this.View == null)
{
result = this.FindView(context);
this.View = result.View;
}
TextWriter output = context.HttpContext.Response.Output;
ViewContext viewContext = new ViewContext(context, this.View, this.ViewData, this.TempData, output);
this.View.Render(viewContext, output);
if (result != null)
{
result.ViewEngine.ReleaseView(context, this.View);
}
}
Based on that code, an object reference exception could be thrown when the code tries to access the RouteData
property from the context (if the name of the view wasn't explicitly given to the return type).
The exception could be thrown by accessing the HttpContext
property. I haven't used Moq well enough to know if it can handle the fact that you haven't told it how to mock the HttpContext
property, but you have told it how to mock the Response
property from the HttpContext
property's type, so that's another area that is suspect to me.
All other uses of context in the method are passing it into other methods, which if those were the problem, then the stack trace would have revealed that.
The easiest way to see which of the two I mentioned are the problem, I would write a quick test to pull those properties from your mocks and see which one causes the exception.
I hit the same problem as this just now and resolved it by setting the HttpContext.Current.
Try adding the following to your unit test code: e.g.
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://mock", ""),
new HttpResponse(new StringWriter()));
One thing that I found useful for debugging this sort of problem rather than using reflector or ILSpy is to turn on debug symbols for the .Net framework code. That way you can attach to your NUnit process and see exactly what line of code is throwing the exception and therefore what you need to Mock in the test.
Shawn Burke has written an excellent blog article detailing how to set this up here: http://blogs.msdn.com/b/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With