【发布时间】:2013-12-22 20:08:12
【问题描述】:
[TestMethod]
public void Can_Login_With_Valid_Credentials()
{
//Arrange
Mock<IMembershipRepository> mockRepository = new Mock<IMembershipRepository>();
Mock<LoginViewModel> mockModel = new Mock<LoginViewModel>();
mockModel.Setup(x => x.IsLoggedIn()).Returns(true);
AccountController target = new AccountController(mockRepository.Object);
//Act
ActionResult result = target.Login(mockModel.Object);
//Assert
Assert.IsNotInstanceOfType(result, typeof(ViewResult));
}
和控制器中的ActionResult
public ActionResult Login(LoginViewModel viewModel)
{
string returnUrl = (string)TempData["ReturnUrl"];
if (ModelState.IsValid)
{
LoginViewModel model = new LoginViewModel(repository, viewModel);
if (model.IsLoggedIn())
{
if (String.IsNullOrEmpty(returnUrl)) return RedirectToAction("Index", "Home");
else return Redirect(returnUrl);
}
else
{
ModelState.AddModelError("Email", "");
ModelState.AddModelError("Password", "");
}
}
return View(viewModel);
}
我在ActionMethod 中模拟model.IsLoggedIn() 时遇到问题,这可能是因为我在ActionMethod 中创建了视图模型LoginViewModel 的新实例。这就是为什么单元测试中的mockModel.Setup(x => x.IsLoggedIn()).Returns(true); 没有缓存它,因为有一个具有该方法的类的新实例。
有什么方法可以在 ActionMethod 中模拟 model.IsLoggedIn() 并使其返回 true?
【问题讨论】:
-
确实是这个问题。您创建一个新的
LoginViewModel对象而不是操作现有对象是否有特定原因? -
一句话,没有。您正在尝试模拟一个具体的实现。如果没有注入依赖项,则无法模拟它。您传入的
LoginViewModel实例不是实际调用IsLoggedIn的实例,因此设置不匹配。 -
目前只有 TypeMock Isolator 或 Fakes 可以帮助您。通过一些重构,您可以轻松地对此进行测试,在您的控制器中创建一个
protected virtual CreateLoginViewModel将允许您通过普通的模拟工具对其进行操作。或者按照 Jeroen 的建议重用模型。 -
是的,我也是这么想的!如果不使用现有的 LoginViewModel,我无法模拟它。
标签: c# unit-testing mocking moq