繁体   English   中英

您如何对相互递归方法进行单元测试?

[英]How do you unit test mutually-recursive methods?

我有三个看起来像这样的函数:

private Node GetNode(Node parentNode)
{
    var node = new node();

    switch (parentNode.NodeType)
    {
       case NodeType.Multiple:    node = GetMultipleNode(parentNode)
       case NodeType.Repeating:   node = GetRepeatingNode(parentNode)
    }

    return node;
}

private Node GetMultipleNode(Node parentNode)
{
    foreach (var child in parentNode.Children)
        return GetNode(child);
}

private Node GetRepeatingNode(Node parentNode)
{
    for (int i=0; i < parentNode.Count; i++)
         return GetNode(new Node(i));  // Assume meaningful constructor for Node
}

鉴于这三种方法是相互递归的,那么如何独立进行单元测试呢?

通常,您不需要单独测试每个方法-您只需测试顶级方法是否正确即可。

但是,如果出于某种原因分别测试每种方法,则可以像测试任何具有依赖项的方法一样使用依赖项注入。 唯一的区别是依赖关系是对象本身。 这是一些示例代码来演示此想法:

class NodeGetter : INodeGetter
{
    public Node GetNode(Node parentNode)
    {
        return GetNode(parentNode, this);
    } 

    public Node GetNode(Node parentNode, INodeGetter nodeGetter)
    {
        switch (parentNode.NodeType)
        {
           case NodeType.Multiple:
               return nodeGetter.GetMultipleNode(parentNode, nodeGetter);
           case NodeType.Repeating:
               return nodeGetter.GetRepeatingNode(parentNode, nodeGetter);
           default:
               throw new NotSupportedException(
                   "Node type not supported: " + parentNode.NodeType);
        }
    }

    public Node GetMultipleNode(Node parentNode, INodeGetter nodeGetter)
    {
        foreach (Node child in parentNode.Children)
        {
            return nodeGetter.GetNode(child);
        }
    }

    public Node GetRepeatingNode(Node parentNode, INodeGetter nodeGetter)
    {
        for (int i = 0; i < parentNode.Count; i++)
        {
            // Assume meaningful constructor for Node
            return nodeGetter.GetNode(new Node(i));
        }
    }
}

在测试nodegetter参数时,请传递一个模拟。

我也将您的方法从私有更改为公共,因为最好只测试类的公共接口。

好吧,您不能“独立地”对它们进行单元测试,因为它们显然是相互依赖的,但是原则上,您可以为GetNode,GetMultipleNode和GetRepeatingNode编写单独的测试,假设有必要从代码中调用每个测试。使用它们。 当然,GetRepeatingNode调用GetNode,依此类推,但这与调用某些完全外部的函数没有什么不同。

顺便说一句,您可能会考虑重构设计并使用多态性而不是NodeType枚举。 只是一个想法:)

如果确实需要,您可以使用接口包装每个方法,并为此方法创建模拟(例如,使用Moq库),或者按照Mark Byers的建议将方法作为参数彼此传递。 但这似乎是过于复杂的解决方案。

如我所见,您的代码中的方法是私有的,您确定为这样的低级内部实现细节编写单元测试是个好主意吗? 我认为这三种方法应该作为一个单元进行测试。 此逻辑分为三种不同的方法,仅用于提高代码的可读性,而这不是某种公共API,因此您真的需要独立测试它们吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM