其他分享
首页 > 其他分享> > 如何测试抽象类的受保护抽象方法?

如何测试抽象类的受保护抽象方法?

作者:互联网

我一直在尝试测试名为TabsActionFilter的抽象类的最佳方法.我保证从TabsActionFilter继承的类将具有一个称为GetCustomer的方法.在实践中,这种设计似乎效果很好.

我遇到一些问题的地方是弄清楚如何测试基类的OnActionExecuted方法.此方法依赖于受保护的抽象GetCustomer方法的实现.我尝试使用Rhino Mocks模拟该类,但似乎无法模拟GetCustomer返回的虚假客户.显然,将方法公开使用将使模拟可用,但受保护的感觉就像更合适的accessibility level.

暂时在测试类中,我添加了一个具体的私有类,该类继承自TabsActionFilter并返回伪造的Customer对象.

>具体课程是唯一的选择吗?
>我是否缺少一种简单的模拟机制,该机制会让Rhino Mocks为GetCustomer提供回报?

作为注释Anderson Imesanswer about 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);
}

测试班和私人班的“模拟”

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确实是需要模拟才能正确地进行隔离测试的东西.

如果需要模拟GetCustomer以便正确隔离和测试TabsActionFilter,则您将需要以某种方式使GetCustomer的实现成为类的可组合部分,而不是继承的方法.实现此目的的最常见方法是使用控制反转/依赖注入.

综上所述,您可以使用TypeMock之类的工具来实现此目的.但是,当您遇到此类难以测试的情况时,通常表明您的班级职责过多,需要分解成较小的组件.

(我不喜欢使用TypeMock FWIW).

标签:unit-testing,tdd,mstest,c,rhino-mocks
来源: https://codeday.me/bug/20191209/2096027.html