单元测试仅调用另外两个方法而没有逻辑的方法的最佳实践是什么?

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的覆盖范围已经足够好,那么我会写一个可能毫无意义的测试,这会出错。

09-25 17:23