我已经阅读了这篇关于如何测试私有方法的文章。我通常不测试它们,因为我总是认为只测试将从对象外部调用的公共方法更快。你测试私有方法吗?我应该一直测试它们吗?


当前回答

测试的目的是什么?

到目前为止,大多数答案都说私有方法是实现细节,只要公共接口经过良好测试并能够正常工作,这些实现细节就不重要(至少不应该)。如果测试的唯一目的是保证公共接口正常工作,那么这是绝对正确的。

就我个人而言,我对代码测试的主要用途是确保将来的代码更改不会导致问题,并且在出现问题时帮助我进行调试。我发现对私有方法的测试就像对公共接口的测试一样彻底(如果不是更彻底的话!),可以进一步达到这个目的。

考虑:您有一个公共方法A,它调用私有方法B。A和B都使用方法C。C被更改(可能由您更改,也可能由供应商更改),导致A开始测试失败。对B进行测试不是很有用吗,即使它是私有的,这样你就知道问题是在A使用C, B使用C,还是两者都有?

Testing private methods also adds value in cases where test coverage of the public interface is incomplete. While this is a situation we generally want to avoid, the efficiency unit testing depends both on the tests finding bugs and the associated development and maintenance costs of those tests. In some cases, the benefits of 100% test coverage may be judged insufficient to warrant the costs of those tests, producing gaps in the public interface's test coverage. In such cases, a well-targeted test of a private method can be a very effective addition to the code base.

其他回答

如果您不测试您的私有方法,您怎么知道它们不会崩溃呢?

我倾向于遵循Dave Thomas和Andy Hunt在他们的书《实用单元测试》中的建议:

一般来说,为了不破坏任何封装 测试(或者就像妈妈常说的,“不要暴露你的私处!”)。大多数 此时,您应该能够通过执行类的 公共方法。如果隐藏了重要的功能 在私人或受保护访问的背后,这可能是一个警告信号 还有一群人在里面挣扎着想出来。

但有时我无法阻止自己测试私有方法,因为它给了我一种安全感,我正在构建一个完全健壮的程序。

I understand the point of view where private methods are considered as implementations details and then don't have to be tested. And I would stick with this rule if we had to develop outside of the object only. But us, are we some kind of restricted developers who are developing only outside of objects, calling only their public methods? Or are we actually also developing that object? As we are not bound to program outside objects, we will probably have to call those private methods into new public ones we are developing. Wouldn't it be great to know that the private method resist against all odds?

我知道有些人会回答说,如果我们正在开发另一个公共方法到那个对象中,那么这个方法应该被测试,就是这样(私有方法可以在没有测试的情况下继续存在)。但这也适用于一个对象的任何公共方法:当开发一个web应用程序时,一个对象的所有公共方法都是从控制器方法调用的,因此可以认为是控制器的实现细节。

那么为什么我们要单元测试对象呢?因为这是非常困难的,不是说不可能,以确保我们正在测试控制器的方法与适当的输入将触发底层代码的所有分支。换句话说,我们在堆栈中的位置越高,测试所有行为就越困难。私有方法也是如此。

对我来说,私人方法和公共方法之间的界限是测试时的心理标准。对我来说更重要的标准是:

该方法是否在不同的地方被多次调用? 这种方法是否复杂到需要测试?

如果我发现私有方法非常庞大、复杂或重要到需要自己的测试,我就把它放在另一个类中,并在那里将它设为公共(方法对象)。然后,我可以轻松地测试以前私有但现在是公共的方法,它现在存在于自己的类中。

对于从测试中调用什么api,公共和私有并不是一个有用的区分,方法和类也不是。大多数可测试单元在一个上下文中是可见的,但在其他上下文中是隐藏的。

重要的是覆盖范围和成本。您需要最小化成本,同时实现项目的覆盖目标(行、分支、路径、块、方法、类、等价类、用例……)不管团队怎么决定)。

因此,使用工具来确保覆盖率,并设计您的测试以减少成本(短期和长期)。

不要让测试变得过于昂贵。 如果只测试公共入口是最便宜的,那就这样做。 如果测试私有方法成本最低,那就这么做。

随着您的经验越来越丰富,您将能够更好地预测何时值得重构以避免测试维护的长期成本。