Is there a way to unit test ASP.NET MVC ViewBag properties set in the view?

Say I have a view with the following code at the top of the page:

@{
    ViewBag.Title = "About Us";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

And I have a controller method:

    public ActionResult About()
    {
        return View();
    }

How can I test that the ViewBag was set properly?

I have tried the following code.

[TestCase]
public void About()
{
    var controller = new AboutController();
    var ar = controller.About() as ViewResult;
    Assert.AreEqual("About Us", ar.ViewBag.Title);
}

But I get the following result when I run the test:

Tests.Controllers.AboutControllerTests.About():
    Expected: "About Us"
    But was: null

Answers


No, you cannot test views like this. The closest you might get is to render the view into a stream writer and then test the generated HTML. It is not something that is commonly done in unit tests. I would recommend you performing web tests in order to verify that the views are correct. You could create web tests with Visual Studio or there's also the free Selenium framework.


Since both the ViewData and ViewBag use the same storage pattern, you should be able to use ViewData[yourKey] in your tests.

So your test will look like this:

[TestCase]
public void About()
{
    var controller = new AboutController();
    var ar = controller.About() as ViewResult;
    Assert.AreEqual("About Us", ar.ViewData["Title"]);
}

Have you tried

Assert.AreEqual("About Us", controller.ViewBag.Title);

It works for me


The ViewResult returned by a controller has only a reference to the view that should be shown. The view is not even resolved at this time. The code there is never executed by your test.

What you should do is set ViewBag properties in the controller, not the view. Usually, the view will only read such values.

hope it helps


For what its worth, I found that the following worked fine:

Assert.AreEqual(_layout, result.ViewBag.Layout);

With result being the ViewResult


[TestMethod]

 public async Task GetData() {
    CtrlNameController controller = new CtrlNameController();

    controller.ViewData["UserId"] = 1;

    ViewResult result = await controller.GetData() as ViewResult;

    Assert.IsNotNull(result);
}

ViewData["UserId"] is equal to View.UserId


Need Your Help

Preventing ActiveRecord save() on an instance

ruby-on-rails ruby activerecord clone

I have an ActiveRecord model object Foo; it represents a standard database row.