3

我是 MVC .NET 的新手(我之前曾在 Ruby On Rails 上工作过)。

我想知道如何编写一个单元测试来检查是否将正确的参数传递到视图中。

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

如何使用用户列表测试 View 是否已通过?我只是模拟 View 静态方法还是有更好的方法?

谢谢!

4

1 回答 1

6

您应该模拟该userManager.GetUsers方法,然后断言控制器操作返回了一个 ViewResult,其模型等于模拟的用户列表。当然,为了能够模拟该userManager.GetUsers方法,该方法需要是虚拟的:

例如:

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

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

现在在您的单元测试中,您可以提供IUsersManager接口的模拟实例并定义GetUsers方法的期望。

使用诸如Rhino Mocks之类的模拟框架是一项微不足道的任务:

[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);
}

并使用MVCContrib.TestHelper它为您提供更流畅的语法,简化了标准 HTTP 工件的模拟,例如上下文、会话、cookie ......:

[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, "");
}
于 2012-05-15T13:26:33.573 回答