我正在尝试为.NET core 2.2 MVC Web应用程序中使用的以下扩展方法编写一些单元测试:
public static string IsSelected(this IHtmlHelper htmlHelper, string controllers, string actions = null, string cssClass = "active")
{
string currentAction = htmlHelper.ViewContext.RouteData.Values["action"] as string;
string currentController = htmlHelper.ViewContext.RouteData.Values["controller"] as string;
IEnumerable<string> acceptedActions = (actions ?? currentAction).Split(',');
IEnumerable<string> acceptedControllers = (controllers ?? currentController).Split(',');
if(actions != null)
{
return acceptedActions.Contains(currentAction) && acceptedControllers.Contains(currentController) ? cssClass : String.Empty;
}
return acceptedControllers.Contains(currentController) ? cssClass : String.Empty;
}
如您所见,它将检查当前RouteData.Values["action"]
中RouteData.Values["controller"]
和ViewContext
的值,并在匹配时返回给定的字符串。
到目前为止,我的单元测试看起来像这样:
public void TestIsSelected()
{
var htmlHelperMock = new Mock<IHtmlHelper>();
htmlHelperMock.Setup(m => m.ViewContext.RouteData.Values["action"]).Returns("Index");
htmlHelperMock.Setup(m => m.ViewContext.RouteData.Values["controller"]).Returns("Home");
var actualPass = Extensions.IsSelected(htmlHelperMock.Object, "Home");
var actualFail = Extensions.IsSelected(htmlHelperMock.Object, "Test");
Assert.AreEqual("active", actualPass);
Assert.AreEqual(string.Empty, actualFail);
}
但是,似乎无法以这种方式设置RouteData.Values[]
值,因为在运行测试时会生成以下错误消息:
Message: Test method ExtensionsTests.TestIsSelected threw exception:
System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: m => m.Values["action"]
我在Moq方面的经验有限,因此可能会错误地设置模拟吗?也许还有另一种方法可以设置这些值,以便测试能够正确运行?我真的很感谢有关如何实现这一目标的任何建议。