Click here to find all the posts relating to the Razor Generator
A few days ago, I blogged about how you can use Razor Generator to precompile your MVC Razor views.
Simple walkthrough to unit test views
After installing RazorGenerator, create an MVC 3 Razor app, using the ‘Internet Application’ template and including the unit test project.
In the previous post, we used precompiled views in a different library, so this time let’s keep them in the MVC project to show something different.
using HtmlAgilityPack;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcApplication2.Views.Home;
using RazorGenerator.Testing;
namespace MvcApplication1.Tests.Views {
[TestClass]
public class HomeViewsTest {
[TestMethod]
public void Index() {
// Instantiate the view directly. This is made possible by
// the fact that we precompiled it
var view = new Index();
// Set up the data that needs to be accessed by the view
view.ViewBag.Message = "Testing";
// Render it in an HtmlAgilityPack HtmlDocument. Note that
// you can pass a 'model' object here if your view needs one.
// Generally, what you do here is similar to how a controller
//action sets up data for its view.
HtmlDocument doc = view.RenderAsHtml();
// Use the HtmlAgilityPack object model to verify the view.
// Here, we simply check that the first <h2> tag contains
// what we put in view.ViewBag.Message
HtmlNode node = doc.DocumentNode.Element("h2");
Assert.AreEqual("Testing", node.InnerHtml.Trim());
}
}
}
A few notes about unit testing views
Unit testing views in ASP.NET MVC is something that was very tricky to do before, due to the fact that the views are normally compiled at runtime. But the use of the Razor Generator makes it possible to directly instantiate view classes and unit test them.
What about partial views?
When designing this view testing framework, we took the approach that we wanted to focus on the output of just one view at a time. Hence, if a view calls @Html.Partial(…) to render a sub-view, we don’t let the sub-view render itself, and instead just render a token to mark where the sub-view would be.
Where do we go from here?
Well, it’ll be interesting to hear what people think about the general idea. We’re interested in two types of feedback.