I've been working on the best way to test an abstract class named TabsActionFilter
. I've guranteed that classes that inherit from TabsActionFilter
will have a method called GetCustomer
. In practice this design seems to work well.
Where I've had some issues is figuring out how to test the OnActionExecuted
method of the base class. This method relies upon the implementation of the the protected abstract GetCustomer
method. I've tried mocking the class using Rhino Mocks but can't seem to mock the return of a fake customer from GetCustomer
. Obviously, flipping the method to public will make mocking available, but protected feels like the more appropriate accessibility level.
For the time being in my test class I've added a concrete private class that inherits from TabsActionFilter
and returns a faked Customer object.
- Is a concrete class the only option?
- Is there a simple mechanism of mocking that I'm missing that would allow Rhino Mocks to provide a return for
GetCustomer
?
As a note Anderson Imes discusses his opinions on this in an answer about Moq and I could be missing something key, but it doesn't seem applicable here.
Class that needs to be tested
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);
}
Test Class and Private Class for "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"
};
}
}
}