我什么时候才能被要求对私人方法进行单元测试?

时间:2017-01-26 11:54:26

标签: c# unit-testing tdd

我正在为我在公司的应用程序中编写的API的实现编写单元测试。这件事还是新手。在寻找关于如何对某些事情进行单元测试的答案时,我遇到了某种模式。它是这样的:

问题:

  

我有这个私有方法,我需要进行单元测试。

最高投票回答:

  

唐'吨

我也遇到了this article反对单位测试私有方法的争论。

基本上我是如何实现API的,我给出的是我先编写代码,然后将单元测试写入"以最坏的方式打破它" (正如我的上级所说)。一旦我发现有问题,我会在代码中修复它。对我而言,这似乎是OOD和TDD的混搭。这是一种合法的做法吗?

我首先得到这么多private方法的原因是我需要将更大的代码块分解为方法。由于这些方法仅应在此API实现的范围内使用,因此我将它们设置为private。由于我的团队建立的文件结构要求我将所有代码写入与API相对应的单个文件中,因此我无法将这些private方法分成新类并将其设置为public

我的上司希望我也测试这些private方法。但是,如果Assert方法上的public成功运行,我是否真的怀疑这是否真的有必要?

从我的观点来看,如果我对public方法的测试返回我期望的值,我推断我的private方法也可以像我预期的那样工作。

或者我错过了什么?

2 个答案:

答案 0 :(得分:6)

核心要点是:存在单元测试以保证您的类在测试下的行为符合预期。

您的课程的行为通过可以从您课程的“外部”调用的方法表现出来。

因此,在尝试直接测试私有方法时,既没有需要也没有感觉

当然,在运行单元测试时测量覆盖率 fair ;以了解代码中的哪些路径。此信息可用于增强测试用例(以获得更多覆盖);或删除生产代码(不是必需的)。

与您的问题保持一致:您不使用TDD来实现私有方法。

您使用TDD创建可以自动执行的特殊形式的“合同”。您验证需要完成的内容;不是如何它实际上是详细的。由于TDD方法包括连续重构,因此尤其如此。你编写测试,将它们变为绿色(通过编写生产代码);然后,在某些时候,您会考虑改进代码的质量。含义:您开始重新测试正在测试的类的内部方面。喜欢:创建更多私人方法,移动内容;甚至可能只创建内部辅助类等等。但是你继续运行你现有的测试......它们应该仍然有效;因为如上所述:你编写它们来检查外部可观察行为(尽可能)。

除此之外:你应该考虑“模糊”你的单元测试驱动到代码中的测试数据而不是担心私有方法。

我的意思是:不要试图手动查找使您的生产代码中断的测试数据,而是查看QuickCheck等尝试自动完成此操作的概念。

最后的话:如果你的管理层继续抨击“测试私人方法”;那么作为工程师,你有责任让他们相信他们错了。并且有很多材料可以支持它。

答案 1 :(得分:1)

此刻分割代码的方式是必需。您正在使用私有方法委派一些工作,因为,其他公共方法需要重复使用它,并且您不希望复制粘贴该代码。当然,由于这些方法无法用作独立方法,因此您将它们保密。

很好,至少你对 DRY (不要重复自己)的原则是正确的。

现在,另一种看待它的方法是,您希望将私有方法与其余代码分开,因为您希望拥有分离关注。如果你这样做,你会发现这些私有方法虽然不能单独使用,但实际上并不属于包含公共方法的类,因为它们没有解决同样的问题:这就是单一责任原则: SOLID 中的S.

您可以做的是将其移至另一个类(我称之为服务),而不是在您的类中使用私有方法,注入他们之前所在的类,并调用这些方法而不是调用私有方法。

你为什么要这样做?

  • 因为它将更容易测试:您委派了很大一部分代码,您不必在大型场景组合下进行测试。
  • 因为你可以注入一个替代实现(想想可维护性:更换砖块比砖块更容易)
  • 因为您可以将此服务的实现(和测试)委托给其他人(您可以让两个开发人员并行处理代码的非常小的区域)
  • 有时,它更有意义,因为这些服务类将被具有相同需求的其他完全不同的类重用,如果它们真正处理一个单一的问题。

这最后一点并不总是发生,但很多时候,确实如此。我发现在自我记录时重新使用现有数据服务更容易:正确命名的服务和正确命名的方法。 (你的同事会更容易发现它们)

现在,您不需要 来测试私有方法...因为它是公开的。

你可能认为这是作弊,因为你只是把它公之于众,但这来自一种非常合法的方法:分离关注点。

最终说明:

我确信你的上司要求你测试这段代码是正确的。他可以补充的一件事就是将这种分离分成不同的类别。此外,请确保使用依赖注入和反转控制容器注入这些类。不要使用new语句对它们进行实例化,否则,您将无法断言使用正确的参数调用了正确的方法!