为提取的方法添加单元测试

时间:2013-02-06 10:11:11

标签: c# unit-testing tdd

假设您正在使用TDD开发产品。您逐步添加测试并最终得到一个大方法。现在是重构的时候了,所以你用较小的方法分离方法。例如;

// Before refactoring.
public void SomeMethod()
{
    // ...
    int sum = numbers.Sum();
    // ...
}

// After refactoring.
public void SomeMethod()
{
    // ...
    int sum = GetSumOfNumbers(numbers);
    // ...
}

private GetSumOfNumbers(int[] numbers)
{
    return numbers.Sum();
}

在此步骤之后,您应该为GetSumOfNumbers方法编写测试吗?我想当我们测试SomeMethod时,我们已经测试了GetSumOfNumbers。但与此同时,可能还有其他方法使用GetSumOfNumbers,尽管它适用于SomeMethod,但它可能不适用于另一个方法。这将有助于我们更快地找到问题(因为测试会给出更具体的错误)。但与此同时,也许这没有用,并增加了冗长。

你怎么看?在示例中,GetSumOfNumbers方法是私有的,所以如果您认为它不应该仅仅因为它是私有的来测试,那么它是否应该被公开测试?

3 个答案:

答案 0 :(得分:4)

您应该测试类的公共API。不要测试私有方法。这样做,将创建一个与您的类太紧密耦合的测试套件。你班上的每一个内部变化都会破坏你的测试套件中的一些测试。

如果你认为你应该测试一个特定的私有方法 - 也许是因为它执行了一些复杂或复杂的逻辑 - 那就是告诉你可能是时候将该方法转移到一个新类中了。

答案 1 :(得分:0)

不,你没有。

这个想法是,当你提取方法时,测试会覆盖你的背部。无论如何,你无法测试私有方法(没有反射)。

通过测试调用GetSumOfNumbers的方法,您将自动对其进行测试。测试覆盖率工具将确认这一点。

答案 2 :(得分:0)

我很想得出结论,在你的设计更加可测试的过程中,你已经走了一半。请注意,对于几乎每个私有方法而言,拥有更多公共方法/创建类绝不是“总是更好”。

我在重构时遵循的正常方法与您正在采用的方法完全相同:

  • 对长方法(1)应用重构“提取方法”。

完成这项工作后,您应该能够将新对象与仅将工作委派给私有方法的微小公共方法区分开来。

  • 应用重构“私有方法介绍类”(2)

如果你的设计/架构有意义!使用依赖注入将对象引用传递给SuT(受测试的主题),以便您可以模拟它的行为。之后,您可以为代表您以前的私有方法的to-be-create类编写新的测试。

我想补充一点。我认为将公共方法的私有方法推广到“公正方法”是一种不好的做法“只是因为你不想为它编写测试”。我认为将方法从私有方法推广到内部方法是一种不好的做法,只是为了测试它们。我将向前迈进一步:我认为允许测试项目访问内部方法是一种不好的做法。对我而言,这一切都表明了设计缺陷。并不意味着这就是不这样做的原因。您可以在代码中添加代码气味,只要它是有意识的选择!在所有其他情况下:保持您的设计可测试,这样您就不必欺骗并将私人方法推广到公共方法。

一个可能过于简单的例子:

public class TheThing
{
    private readonly ISummator _summator;

    public TheThing(ISummator summator)
    {
        _summator = summator;
    }

    public void SomeMethod()
    {
        _summator.SumStuff();
    }
}