我一直在研究如何测试一个名为TabsActionFilter
的抽象类的最佳方法。我已经保证了继承自TabsActionFilter
的类将拥有一个名为GetCustomer
的方法。在实践中,这种设计似乎运作良好。
我的问题在于,我不知道如何测试基类的OnActionExecuted
方法。此方法依赖于受保护的抽象GetCustomer
方法的实现。我曾尝试使用Rhino Mocks模拟类,但似乎无法模拟从GetCustomer
返回一个虚假的客户。很明显,将该方法转换为公共方法将使模拟可用,但由于protected是更适当的访问级别,所以并未采取此方式。
目前,在我的测试类中,我添加了一个具体的私有类,该类继承自TabsActionFilter
并返回一个虚假的Customer对象。
- 具体类是唯一的选项吗?
- 有我所忽略的简单的模拟机制可以允许Rhino Mocks提供
GetCustomer
的返回值吗?
作为注释Anderson Imes在关于Moq的答案中谈到了他的意见,我可能会遗漏一些关键的信息,但它似乎不适用于这里。
需要测试的类:
public abstract class TabsActionFilter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Customer customer = GetCustomer(filterContext);
List<TabItem> tabItems = new List<TabItem>();
tabItems.Add(CreateTab(customer, "Summary", "Details", "Customer",
filterContext));
tabItems.Add(CreateTab(customer, "Computers", "Index", "Machine",
filterContext));
tabItems.Add(CreateTab(customer, "Accounts", "AccountList",
"Customer", filterContext));
tabItems.Add(CreateTab(customer, "Actions Required", "Details",
"Customer", filterContext));
filterContext.Controller.ViewData.PageTitleSet(customer.CustMailName);
filterContext.Controller.ViewData.TabItemListSet(tabItems);
}
protected abstract Customer GetCustomer(ActionExecutedContext filterContext);
}
"Mocking"的测试类和私有类
public class TabsActionFilterTest
{
[TestMethod]
public void CanCreateTabs()
{
// arrange
var filterContext = GetFilterContext(); //method omitted for brevity
TabsActionFilterTestClass tabsActionFilter =
new TabsActionFilterTestClass();
// act
tabsActionFilter.OnActionExecuted(filterContext);
// assert
Assert.IsTrue(filterContext.Controller.ViewData
.TabItemListGet().Count > 0);
}
private class TabsActionFilterTestClass : TabsActionFilter
{
protected override Customer GetCustomer(
ActionExecutedContext filterContext)
{
return new Customer
{
Id = "4242",
CustMailName = "Hal"
};
}
}
}
GetCustomer
方法的实现是由继承类负责的。不幸的是,通过构造函数进行依赖注入在这里行不通,因为TabsActionFilter
继承自ActionFilterAttribute
,这限制了我只能使用默认构造函数。我猜我可以在继承类上使用属性注入来添加一个服务,以允许获取客户。但这真的是更好的设计吗? - ahsteele