ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-12-09 03:06:13  阅读:373  来源: 互联网

标签:unit-testing tdd mstest c rhino-mocks


我一直在尝试测试名为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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有