我正在四处学习如何对ASP.NET MVC控制器操作进行单元测试。具体来说,我正在尝试模拟ControllerContext,以便我可以测试访问HttpContext.Current.User.Identity.Name的操作。
我正在使用Moq。
在我打开MockBehavior.Strict之前,事情进展顺利。我知道如果代码无法调用我标记为Verifiable的东西,这会抛出异常。显然,如果我没有提供设置(如IsChildAction)的“额外”方法不被调用,它也会抛出异常。
[TestMethod]
public void Index_Get_AccessesUserIdentityName()
{
// Arrange
var mock = new Mock<ControllerContext>(MockBehavior.Strict);
mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("treycarroll").Verifiable();
HomeController controller = new HomeController();
controller.ControllerContext = mock.Object;
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
mock.Verify();
...
}
以下是我正在测试的Controller操作:
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!"+User.Identity.Name;
return View();
}
返回View()时触发异常;声明被执行。错误消息告诉我,我需要一个调用IsChildAction的设置方法,所以我将我的测试类更新为:
[TestMethod]
public void Index_Get_AccessesUserIdentityName()
{
// Arrange
var mock = new Mock<ControllerContext>(MockBehavior.Strict);
string expectedUserName = "treycarroll";
mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(expectedUserName).Verifiable();
mock.SetupGet(m => m.IsChildAction).Returns(true).Verifiable();
HomeController controller = new HomeController();
controller.ControllerContext = mock.Object;
// Act
ViewResult result = controller.Index() as ViewResult;
string actualUserName = controller.ControllerContext.HttpContext.User.Identity.Name;
// Assert
mock.Verify();
Assert.AreEqual(actualUserName, expectedUserName);
Assert.IsNotNull(result);
}
...
之后我得到一个类似的错误,没有关于ControllerContext.RouteData的设置方法。通过消除过程,我可以最终为所有丢失的调用添加Setup方法,但这似乎不对。也许我误解了MockBehavior.Strict的使用,但我认为你打开它以避免获取属性的默认值(例如我想要检查的User对象的null)。我在这里缺少什么?
答案 0 :(得分:5)
如果有任何不同于预期的情况,严格模拟将立即失败。所以这意味着,如果未在期望中指定的任何方法调用将失败。另一方面,非严格模拟忽略,例如调用