2

假设您正在使用 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方法是私有的,所以如果你认为它不应该仅仅因为它是私有的而被测试,那么如果它是公共的,它应该被测试吗?

4

3 回答 3

5

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

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

于 2013-02-06T10:13:32.570 回答
1

不,你没有。

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

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

于 2013-02-06T10:13:44.693 回答
1

我很想得出这样的结论:在使设计更可测试的过程中,您已经完成了一半。请注意,拥有更多公共方法/为几乎每个私有方法创建一个类绝不是“总是更好”。

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

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

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

  • 应用重构“为私有方法引入类”(2)

如果它在您的设计/架构中有意义!使用依赖注入将对象引用传递给您的 SuT(被测对象),以便您可以模拟它的行为。之后,您可以为代表您以前的私有方法的待创建类编写新测试。

我想补充一件事。我认为将私有方法推广为公共方法是一种不好的做法,“只是因为你不想为它编写测试”。我还认为将方法从私有提升到内部只是为了测试它们是一种不好的做法。我会更进一步:我认为允许测试项目访问内部方法是一种不好的做法。对我来说,这都是设计缺陷的迹象。并不意味着这就是不这样做的原因。您可以在代码中添加代码气味,只要这是有意识的选择!在所有其他情况下:保持您的设计可测试,这样您就不必作弊并将私有方法提升为公共方法。

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

public class TheThing
{
    private readonly ISummator _summator;

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

    public void SomeMethod()
    {
        _summator.SumStuff();
    }
}
于 2013-02-06T10:48:46.623 回答