Unit testing a rendered View in ASP.NET MVC
I'm sorry to be beating this drum again, but I've been searching and searching for a way to unit test a rendered view in ASP.NET MVC (currently using v2).
I'm not 100% satisfied with using WatiN or Selenium to do this, they both are great tools, but take far too long to run a test for what is such a simple scenario, and are testing way way more than I need.
I am also deeply unsatisfied with the "Views should not be tested" mantra that seemingly stems from the root cause of Views, in their current state, just aren't testable outside of a larger integration test. :)
I've already got a test on the Controller with "AssertViewRendered().For("Index").WithViewData()" etc. I am simply wanting to cover that the data is displayed by the view when it is on the Model.
Imagine this simple scenario:
controller:
public class SimpleController : Controller
{
public void Index()
{
var vm = new SimpleViewModel { Message = "Hello world!" };
return View(vm);
}
}
And this simple view model:
public class SimpleViewModel
{
public string Message { get; set; }
}
And a simple view:
`<%@ Page Language="C#"` `Inherits="System.Web.Mvc.ViewPage<SimpleViewModel>" %>`
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1><%= Model.Message %>&l开发者_高级运维t;/h1>
</body>
</html>
How do I automate with a simple unit test that the View actually uses the Message property, without needing to use heavy-weight integration testing tools like WatiN, and without a web server?
Something like this would be ideal:
[TestMethod]
public void ShouldDisplayMessage()
{
const string helloWorld = "Hello world!";
var view = new SimpleView(new SimpleViewModel { Message = helloWorld });
var result = view.GetRenderedString();
Assert.IsTrue(result.Contains(helloWorld));
}
This issue is that your View file contains other information that effects the view (aka the markup). You can test the view model to has the correct information in the view model but I'm not sure that's exactly what you want.
You can cast your ViewResult.ViewData.Model as you view model and assert values from there.
[Test]
public Test()
{
var homeController = new HomeController();
var result = homeController.About() as ViewResult();
Assert.IsInstanceOf(typeof(MyViewModel),result.ViewData.Model);
var myModel = result.ViewData.Model as MyViewModel;
Assert.That(myModel.Name,Is.EqualTo("Hello World") );
}
If you used the spark view engine things might be a little easier
http://darrell.mozingo.net/2010/01/28/in-memory-view-rendering-with-spark/
精彩评论