我有三个看起来像这样的函数:
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
}
鉴于这三种方法是相互递归的,那么如何单独测试它们呢?
答案 0 :(得分:5)
通常你不需要单独测试每个方法 - 你可以测试顶级方法做正确的事。
但是,如果由于某种原因你希望分别测试每个方法,你可以使用依赖注入,就像测试任何具有依赖关系的方法一样。这里唯一的区别是依赖是对象本身。以下是一些示例代码来演示这个想法:
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参数时,传递一个mock。
我还将您的方法从私有更改为公开,因为最好只测试您的类的公共接口。
答案 1 :(得分:1)
好吧,你不能“独立”单独测试它们,因为它们显然彼此依赖,但原则上你当然可以为GetNode,GetMultipleNode和GetRepeatingNode编写单独的测试,假设从它们中调用每一个是有意义的。使用它们的代码。当然,GetRepeatingNode调用GetNode,依此类推,但这与调用一些完全外部函数没有区别。
顺便提一下,您可以考虑重构您的设计并使用多态而不是NodeType枚举。只是一个想法:)
答案 2 :(得分:0)
如果确实需要,可以使用接口包装每个方法并为此方法创建模拟(例如使用Moq库)或将方法作为Mark Byers建议的参数相互传递。但似乎这是一个过于复杂的解决方案。
正如我所看到的,代码中的方法是私有的,您确定,为这种低级别的内部实现细节编写单元测试是个好主意吗?我相信这三种方法应该作为一个单元进行测试。这个逻辑分为三种不同的方法,只是为了提高代码的可读性,这不是某种公共API,所以你真的需要独立测试它们吗?