I need some help here, how do I easily test my controller?
If you have ever tried to test any of the framework aspects of a controller, such as making sure the response code is a 404, you probably know that it's not as easy as you had hoped. The following is a base class that I have created that I use in my testing to set up all of the dependencies using Rhino Mocks. In addition to this it is necessary to create a "Testable" version of your controller, of which I have an example bellow.
Test Base Class
public class ControllerBaseTester
{
protected readonly IBlogConfiguration Configuration = MockRepository.GenerateStub<IBlogConfiguration>();
protected readonly HttpContextBase HttpContext = MockRepository.GenerateStub<HttpContextBase>();
protected readonly RouteData RouteData = new RouteData();
protected readonly RequestContext Context;
protected readonly StringBuilder ResponseString = new StringBuilder();
protected readonly TextWriter ResponseWriter;
protected readonly HttpResponseBase Response;
public ControllerBaseTester()
{
ResponseWriter = new StringWriter(ResponseString);
Response = new HttpResponseWrapper(new HttpResponse(ResponseWriter));
HttpContext.User = Test.AuthorizedUser;
HttpContext.Expect(x => x.Response).Return(Response);
Context = new RequestContext(HttpContext, RouteData);
Configuration.Stub(x => x.Configuration).Return(Test.Configuration);
}
}
Creating a Testable Controller
class TestableController : BlogController
{
TestableController(IBlogService blogService, IBlogConfiguration configuration)
: base(blogService, configuration)
{
}
private void Init(RequestContext context)
{
Initialize(context);
}
public static BlogController Create(RequestContext context, IBlogService blogService, IBlogConfiguration configuration)
{
var result = new TestableController(blogService, configuration);
result.Init(context);
return result;
}
}
Tuesday, February 02, 2010
Passing Configuration Data to the Master Page in ASP.NET MVC
One of the common activities that I have found myself doing lately whenever I create a new project is to identify a way of loading configuration information and customizing the behavior of the Master Page. The way I initially went about solving this problem was to create a base class and have all of my Page ViewModel’s inherit from it. This caused two different things that I had to constantly maintain, making sure all of my ViewModel’s inherited from this MasterViewModel and then remembering to set the data every time a ViewResult is returned in an Action.
public class MasterViewModel : IMasterViewModel
{
public string SiteName { get; set; }
}
I was able to take care of the second concern by simply creating a base controller that all of my controllers would inherit from and then override View(string viewName, string masterName, object model) { … } so that the settings are automatically injected into the model.
protected override ViewResult View(string viewName, string masterName, object model)
{
((MasterViewModel)model).SiteName = "Example";
return base.View(viewName, masterName, model);
}
In order to get around the smell of forcing my ViewModel’s to inherit from a base class I put the MasterViewModel into the ViewData dictionary that is returned in the ViewResult.
protected override ViewResult View(string viewName, string masterName, object model)
{
ViewResult result = base.View(viewName, masterName, model);
result.ViewData[Data.Site] = _blogConfiguration.Configuration;
return result;
}
Once I had this in place, I created a new ViewMasterPage with a property that exposed the data that was put into ViewData. This then allowed me to have a strongly typed referenced from the Master Page.
<%@ Import Namespace="Azure.Domain.Models"%>
<%@ Master Language="C#" Inherits="Azure.Web.Views.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title><%= SiteConfiguration.Name %><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.1.min.js" type="text/javascript" language="javascript"></script>
<script src="http://ajax.microsoft.com/ajax/jQuery.Validate/1.6/jQuery.Validate.min.js" type="text/javascript" language="javascript"></script>
<asp:ContentPlaceHolder ID="HeaderContent" runat="server" />
</head>
<body>
<div id="header">
<h1><%= SiteConfiguration.Name %></h1>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div id="footer">
©<%= DateTime.UtcNow.Year %> <%= SiteConfiguration.Owner %>
</div>
</body>
</html>
All examples are taken from the work I have been doing as a part of creating my own blog engine on Azure. You can track my progress and grab source code on my AzureBlog project site on CodePlex.
Tuesday, February 02, 2010IE 6 is Dead
I just received this email from google. I think we can all celebrate this.
Tuesday, February 02, 2010Dear Google Apps admin,
In order to continue to improve our products and deliver more sophisticated features and performance, we are harnessing some of the latest improvements in web browser technology. This includes faster JavaScript processing and new standards like HTML5. As a result, over the course of 2010, we will be phasing out support for Microsoft Internet Explorer 6.0 as well as other older browsers that are not supported by their own manufacturers.
We plan to begin phasing out support of these older browsers on the Google Docs suite and the Google Sites editor on March 1, 2010. After that point, certain functionality within these applications may have higher latency and may not work correctly in these older browsers. Later in 2010, we will start to phase out support for these browsers for Google Mail and Google Calendar.
Google Apps will continue to support Internet Explorer 7.0 and above, Firefox 3.0 and above, Google Chrome 4.0 and above, and Safari 3.0 and above.
Starting this week, users on these older browsers will see a message in Google Docs and the Google Sites editor explaining this change and asking them to upgrade their browser. We will also alert you again closer to March 1 to remind you of this change.
In 2009, the Google Apps team delivered more than 100 improvements to enhance your product experience. We are aiming to beat that in 2010 and continue to deliver the best and most innovative collaboration products for businesses.
Thank you for your continued support!
Sincerely,
The Google Apps team