Caster Troy
Caster Troy

Reputation: 2866

How Can I Test That My View Is Rendered Correctly?

I just wrote my first unit test and now I have some questions. Here is said test:

[Test]
public void IndexShouldReturnPosts()
{
    // arrange
    var repository = Mock.Create<IRepository>();
    var posts = new [] 
    {
        new Post { Title = "Hello", Slug = "hello", Content = "Some post."},
        new Post { Title = "Goodbye", Slug = "goodbye", Content = "Some post."}
    };
    Mock.Arrange(() => repository.GetAll()).Returns(posts);
    var controller = new HomeController(repository);

    // act
    var result = controller.Index();
    var model = (Post[]) result.Model;

    // assert
    CollectionAssert.AreEqual(posts, model);
}

This test passes, and I understand why. However, the web page does not actually work as expected as no view cannot be found.

I think (and please correct me if I am wrong) that I need to write another test to validate that view is rendered correctly but I do not know how.

How can I test that my view is rendered correctly?

Upvotes: 1

Views: 421

Answers (3)

Paul Abbott
Paul Abbott

Reputation: 7211

Unit tests test...a single unit. If you are trying to test the controller and the view at the same time, it is not a unit test. If you want to do an integration test and get the actual html that is produced, check out http://blog.stevensanderson.com/2009/06/11/integration-testing-your-aspnet-mvc-application/

Edit: You could probably make a unit test for the view provided you mocked/faked the controller and the model, but it might get a bit complicated because you would also need to mock the ControllerContext (see Mocking Asp.net-mvc Controller Context). Once that is all set up, you could render the view into html using something like http://codetunnel.com/how-to-render-an-aspnet-mvc-view-to-a-string-from-within-the-controller. Just use FindView instead of FindPartialView. If there are any errors in your cshtml, an exception will be thrown which you can detect. You can also inspect the html text string to see if the elements/data you are expecting are present.

Upvotes: 1

NWard
NWard

Reputation: 2086

You can test a controller action which returns a ViewResult (which is what you're trying to do, I think) like so:

var myController = new MyController([mocked dependencies here]);
myController.ControllerContext = mockedControllerContext;
var result = myController.MyActionWhichReturnsAViewResult();

Assert.IsNotNull(result);
Assert.IsInstanceOf<ViewResult>(result);
Assert.That(result.ViewName == [expectedViewName])

Which is to say, you'll need to mock up not just the dependencies of your controller (if it needs data access, etc.), but also the HTTP context in which the controller is intended to live. The Moq library makes this pretty easy, and here's another Stack Overflow question which may help you with it: How do I mock the HttpContext in ASP.NET MVC using Moq?

Upvotes: 1

TGH
TGH

Reputation: 39268

I would consider doing web testing instead if you want to test that the correct view is rendered. My framework of choice is Selenium, but there are others available.

It let's you automate a browser through a rich c# API

Upvotes: 0

Related Questions