单元测试仅调用另外两个方法而没有逻辑的方法的最佳实践是什么?
internal ICollection<ObjA> FunctionA()
{
IEnumerable<ObjB> b = _factory.FunctionB();
return FunctionC(b);
}
_factory.FunctionB()
和FunctionC(b)
都具有单元测试,因此如果这些方法失败了,我们将知道。我正在考虑伪造这两个函数,只是进行了单元测试,以确保从
FunctionA()
调用方法。但是,如果FunctionB()
或FunctionC()
更改,则FunctionA()
可能会成为误报。 最佳答案
我倾向于不对私有方法或内部方法进行单元测试,因为在对公共API进行单元测试时应执行它们。
假设这是一个公共方法,我将进行测试,以根据私有成员_factory的状态检查您在调用FunctionA()时期望的返回值。假设您可以控制_factory的输出(通过它是可模拟的接口,可子类的基类,或者仅是用已知值实例化并传递给该类的构造函数),则可以确保获得预期的输出基于该初始输入的FunctionA。
如果您发现每次更新FunctionB或FunctionC都会得到误报,我会问为什么FunctionA根本存在。更有可能的情况是,在FunctionA上中断的单元测试将导致您更改FunctionA的内部实现,因为对FunctionB和FunctionC的更改不再使它们成为FunctionA的合适实现,或者它们将导致您为以下功能添加单元测试这些功能可修复FunctionA中的间接损坏。
在此特定示例中,似乎FunctionA只是使用内部工厂类已指定的数据源将ObjB转换为ObjA的包装。对于这种特定情况,我将对FunctionA进行测试,以便在更高级别的要求发生变化时(因为实施了有关如何将ObjB转换为ObjA的新规则),因此我可以根据哪个将新逻辑放入FunctionA或FunctionC中。我认为比较合适。
例:
internal ICollection<ObjA> FunctionA()
{
IEnumerable<ObjB> b = _factory.FunctionB();
// in the future unit test may drive that a different implemetation is used
// based on some data about b.
if(b.SomeCondition())
return FunctionC(b);
else
return FunctionD(b);
}
或者可能是C需要改变
internal ICollection<ObjA> FunctionC(IEnumerable<ObjB> objBEnumerable)
{
ICollection<ObjA> objACollection = initializeCollection();
foreach(var objB in objBEnumerable)
{
//updated logic to create objA from objB goes here
objACollection.Add(createdObjA);
}
return objACollection;
}
基本上,您的问题的答案是“取决于”,但是如果将来在第一个代码示例中需要转移A的情况下,如果函数B和C的覆盖范围已经足够好,那么我会写一个可能毫无意义的测试,这会出错。