Question

I am using T4MVC in my ASP.NET MVC 3 project. I have the following basic test:

[TestMethod]
public void IndexReturnsIndexView()
{
    var controller = new HomeController();
    var result = controller.Index();

    result.AssertViewRendered().ForView(MVC.Home.Views.Index);
}

The test fails if the controller method returns the default View:

public virtual ActionResult Index()
{
    return View();
}

The error given is:

MvcContrib.TestHelper.ActionResultAssertionException: Expected view name '~/Views/Home/Index.cshtml', actual was ''

But the test passes if I override the View to specify which viewName to return:

public virtual ActionResult Index()
{
    return View(MVC.Home.Views.Index);
}

I tried using the following assertion, but still not luck:

result.AssertViewRendered().ForView(MVC.Home.Index().GetT4MVCResult().Action);

The following error is raised:

MvcContrib.TestHelper.ActionResultAssertionException: Expected view name 'Index', actual was ''

I then realized that I had misread the assertion failure, so I changed the test to this:

result.AssertViewRendered().ForView(String.Empty);

The test passes, but the test itself seems to be useless.

Preferably I don't want to have to specify all views by name, so how do I test this? To clarify, I am using the MvcContrib.Mvc3.TestHelper-ci 3.0.96.0, which I installed today from NuGet.

UPDATE

This isn't an answer to the question, but I have started doing the following instead, which provides more value as a test case:

using (var controller = new FeatureController(mockGateway))
{
    // Act
    var result = controller.Index();
    var model = result.ViewData.Model as MyModel;

    // Assert
    Assert.IsNotNull(model, "Model is null or wrong type");
    result.AssertViewRendered().WithViewData<MyModel>();

    // Alternative Assert for model data
    Assert.IsTrue(model.Items.Count > 0);
}
Was it helpful?

Solution

I left this open for a considerable amount of time, so that anyone else could answer if they chose to. I'll now answer this myself.

The following checks to make sure that the view returned contains the expected model, and more appropriately data within that model. This is a much better unit test for the controller in question.

using (var controller = new FeatureController(mockGateway))
{
    // Act
    var result = controller.Index();
    var model = result.ViewData.Model as MyModel;

    // Assert
    Assert.IsNotNull(model, "Model is null or wrong type");
    result.AssertViewRendered().WithViewData<MyModel>();

    // Alternative Assert for model data
    Assert.IsTrue(model.Items.Count > 0);
}

OTHER TIPS

AssertViewRendered().ForView() tests against the view name that you explicitly pass to View() is your controller action. If, as you're doing, you don't specify a view name in your action, then .ForView() will be testing against an empty string, as you've seen.

If you called View("Index"); in your action, you could call .ForView("Index") in your test.

I would think that this assertion would be most useful if your action could return different possible views.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top