Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 %></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));
    }
like image 298
Jenk Avatar asked Mar 10 '11 16:03

Jenk


People also ask

What is rendered in view of MVC?

A view renders the appropriate UI by using the data that is passed to it from the controller. This data is passed to a view from a controller action method by using the View method. The Views folder is the recommended location for views in the MVC Web project structure.

What is view in MVC with example?

A view is used to display data using the model class object. The Views folder contains all the view files in the ASP.NET MVC application. A controller can have one or more action methods, and each action method can return a different view. In short, a controller can render one or more views.


1 Answers

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/

like image 146
Johnno Nolan Avatar answered Oct 30 '22 11:10

Johnno Nolan