MVC .NET Unit Test: how to test arguments are sent to view from controller

asp.net-mvc-3, controllers, mstest, unit-testing

Solution

You should mock the `userManager.GetUsers` method and then assert that the controller action returned a ViewResult with model that equals to the mocked list of users. Of course in order to be able to mock the `userManager.GetUsers` method this method needs to be virtual:

For example:

public class HomeController: Controller
{
    private readonly IUsersManager _usersManager;
    public HomeController(IUsersManager usersManager)
    {
        _usersManager = usersManager;
    }

    public ActionResult Users()
    {
        var users = _usersManager.GetUsers();
        return View(users);
    }    
}

Now in your unit test you could provide a mock instance of the `IUsersManager` interface and define expectations for the `GetUsers` method.

Using a mocking framework such as Rhino Mocks this is a trivial task:

[TestMethod]
public void Users_Action_Should_Query_The_UserManager_Repository_And_Pass_The_Result_To_The_View()
{
    // arrange
    var expectedUsers = new User[] { new User() };
    var usersManagerStub = MockRepository.GenerateStub<IUsersManager>();
    usersManagerStub.Stub(x => x.GetUsers()).Return(expectedUsers);
    var sut = new HomeController(usersManagerStub);

    // act
    var actual = sut.Users();

    // assert
    Assert.IsInstanceOfType(actual, typeof(ViewResult));
    var viewResult = actual as ViewResult;
    Assert.AreEqual(expectedUsers, viewResult.Model);
}

and using MVCContrib.TestHelper it provides you more fluent syntax simplifies the mocking of standard HTTP artifacts such as the context, session, cookies, ...:

[TestMethod]
public void Users_Action_Should_Query_The_UserManager_Repository_And_Pass_The_Result_To_The_View()
{
    // arrange
    var expectedUsers = new User[] { new User() };
    var usersManagerStub = MockRepository.GenerateStub<IUsersManager>();
    usersManagerStub.Stub(x => x.GetUsers()).Return(expectedUsers);
    var sut = new HomeController(usersManagerStub);

    // act
    var actual = sut.Users();

    // assert
    actual
        .AssertViewRendered()
        .WithViewData<User[]>()
        .ShouldEqual(expectedUsers, "");
}

Problem

I am new to MVC .NET (I have previously worked on Ruby On Rails). I was wondering how I could write a unit test that would check that the correct arguments are passed into the view. ``` public ActionResult Users() { var users = userManager.GetUsers(); return View(users); } ``` How do I test that the View has been passed with the list of users? Do I simply mock the View static method or is there a better approach? Thanks!

Original source