Reputation: 2866
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
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
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
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