Asp.net mvc 控制器OnActionExecuting事件中的单元测试逻辑
在我的控制器的OnActionExecuting事件中有一个自定义逻辑来设置页面标题,如果未使用操作方法上的属性设置,则会为标题设置默认值:Asp.net mvc 控制器OnActionExecuting事件中的单元测试逻辑,asp.net-mvc,unit-testing,moq,Asp.net Mvc,Unit Testing,Moq,在我的控制器的OnActionExecuting事件中有一个自定义逻辑来设置页面标题,如果未使用操作方法上的属性设置,则会为标题设置默认值: [PageTitle("Overriden page title")] public ActionResult About() { return View(); } public ActionResult Error() { return View(); } protected override void OnActionExecuti
[PageTitle("Overriden page title")]
public ActionResult About()
{
return View();
}
public ActionResult Error()
{
return View();
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Page title
var title = filterContext.ActionDescriptor.GetCustomAttributes(typeof(PageTitleAttribute), false);
if (title.Length == 1)
ViewBag.Title = ((PageTitleAttribute)(title[0])).Parameter;
else
ViewBag.Title = "Default Website Title";
}
如何对该功能进行单元测试?这就是我最后要做的(可能对任何面临类似问题的人都有帮助) 1) 我将控制器中的代码拆分为以下内容:
public class BaseController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
SetupMetadata(filterContext);
base.OnActionExecuting(filterContext);
}
public virtual void SetupMetadata(ActionExecutingContext filterContext)
{
//Page title
var title = filterContext.ActionDescriptor.GetCustomAttributes(typeof(PageTitleAttribute), false);
if (title.Length == 1)
ViewBag.Title = ((PageTitleAttribute)(title[0])).Parameter;
else
ViewBag.Title = "Default Page Title";
}
}
2) 从basecontroller派生my HomeController
3) 然后使用以下工具对其进行单元测试:
[TestClass]
public class BaseControllerTests
{
[TestMethod]
public void OnActionExecuting_should_return_attribute_value_when_set()
{
var ctx = new Mock<ActionExecutingContext>();
var controller = new HomeController();
ctx.Setup(c => c.Controller).Returns(controller);
ctx.Setup(c => c.ActionDescriptor.GetCustomAttributes(typeof(PageTitleAttribute), false)).Returns(new object[] { new PageTitleAttribute("Overriden Title") });
controller.SetupMetadata(ctx.Object);
Assert.AreEqual("Overriden Title", controller.ViewBag.Title);
}
[TestMethod]
public void OnActionExecuting_should_return_default_attribute_values_if_attributes_are_missing()
{
var ctx = new Mock<ActionExecutingContext>();
var controller = new HomeController();
ctx.Setup(c => c.Controller).Returns(controller);
ctx.Setup(c => c.ActionDescriptor.GetCustomAttributes(typeof(PageTitleAttribute), false)).Returns(new object[0]);
controller.SetupMetadata(ctx.Object);
Assert.AreEqual("Default Page Title", controller.ViewBag.Title);
}
}
[TestClass]
公共类BaseControllerTests
{
[测试方法]
public void OnActionExecuting_应在_set()时返回_属性_值
{
var ctx=新的Mock();
var controller=新的HomeController();
设置(c=>c.Controller).返回(Controller);
Setup(c=>c.ActionDescriptor.GetCustomAttributes(typeof(PageTitleAttribute),false)).Returns(新对象[]{new PageTitleAttribute(“覆盖的标题”)});
controller.SetupMetadata(ctx.Object);
Assert.AreEqual(“覆盖的标题”,controller.ViewBag.Title);
}
[测试方法]
public void OnActionExecuting如果缺少属性,则应返回默认属性值
{
var ctx=新的Mock();
var controller=新的HomeController();
设置(c=>c.Controller).返回(Controller);
Setup(c=>c.ActionDescriptor.GetCustomAttributes(typeof(PageTitleAttribute),false)).Returns(新对象[0]);
controller.SetupMetadata(ctx.Object);
AreEqual(“默认页面标题”,controller.ViewBag.Title);
}
}
为什么不在PageTitle操作筛选器内实现上述OnActionExecuting逻辑,并对操作筛选器本身进行单元测试?@Spock我可以这样做,但问题是ActionFilterAttribute只有在操作方法上进行修饰时才起作用。我希望设置/返回默认值,以防decorator未应用操作。