[英]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.