Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 将私有方法更改为单元测试的受保护或包私有-好还是坏?_Unit Testing_Tdd - Fatal编程技术网

Unit testing 将私有方法更改为单元测试的受保护或包私有-好还是坏?

Unit testing 将私有方法更改为单元测试的受保护或包私有-好还是坏?,unit-testing,tdd,Unit Testing,Tdd,我正在研究TDD,最近正在寻找如何正确地对私有方法进行单元测试。堆栈溢出中流行的答案是: 使用反射使私有方法可以从外部访问 不要测试私有方法。(请改用公共方法。) 根据评论部分的不同意见,似乎每个人都有自己的规则。然后我发现这表明了一个相当大胆的方法 使私有方法受保护或包私有。将测试代码放在同一个包中。 为可测试性而设计意味着设计代码以使其更易于测试。要做到这一点,你可能必须打破我们在大学里学到的一些原则,比如封装 尽管TDD的原则是为可测试性设计代码,但破坏封装对我来说并不合适。这种

我正在研究TDD,最近正在寻找如何正确地对私有方法进行单元测试。堆栈溢出中流行的答案是:

  • 使用反射使私有方法可以从外部访问
  • 不要测试私有方法。(请改用公共方法。)
根据评论部分的不同意见,似乎每个人都有自己的规则。然后我发现这表明了一个相当大胆的方法

  • 使
    私有
    方法
    受保护
    包私有
    。将测试代码放在同一个包中。 为可测试性而设计意味着设计代码以使其更易于测试。要做到这一点,你可能必须打破我们在大学里学到的一些原则,比如封装


尽管TDD的原则是为可测试性设计代码,但破坏封装对我来说并不合适。这种方法是一种好方法吗?

如果您同意将Guava库添加为依赖项,那么可以将方法
包设置为私有的
,并用注释标记它


我假设您使用的是Java,尽管您没有明确说明这一点。

我认为正确的答案是:不要测试私有方法。 如果您觉得需要测试私有方法,可能会出现以下两种情况之一:

  • 该方法不必是私有的:也许可以通过它所在的对象的API访问该方法。在这种情况下,将其更改为public(或其他非private)。另一种选择是将方法的行为放在另一个对象的公共方法中,并为其构建一些专用测试
  • 方法必须是私有的,因此您正在测试一些不应该测试的东西。您正试图编写与正在测试的对象耦合太多的测试。根据定义,私有方法是不稳定的,它们可以在一段时间内频繁更改。这些更改将破坏直接验证私有方法的每个测试

如果我必须选择,我会选择测试覆盖率而不是封装。@Robert但既然每个私有方法都迫使我选择,这难道不意味着不再有私有方法了吗?我不会对DTO这样太琐碎的东西进行单元测试。但是“你在测试一些你不应该测试的东西”对我来说有些陌生。什么样的方法不应该被测试?另一个问题。还有一些私有方法非常复杂,需要测试。我该怎么办?我的想法是,如果可能的话,将该方法转移到一个新的类中,并将其公开。也许有更好的方法?或者没有解决办法,不应该测试?我说的“您正在测试不应该测试的东西”的意思是,您可能不需要对私有方法内部的逻辑进行特定测试。也许您可以通过为使用私有方法代码的公共方法创建测试来测试私有代码。通过这种方式,您可以有效地测试对象的公共行为,您可以测试作为公共API一部分的某些方法,因此,根据定义,它必须是稳定的。但是,因此,您也在测试需要执行的私有代码,以满足上面提到的“公共行为”。正如我在答案中所写的,私有方法可以在自己的对象中移动,并且可以成为公共的。或者,您可以通过测试使用该逻辑的另一个公共方法来测试私有逻辑。不要把单元测试看作是每个方法的测试,而是试着从行为的角度来考虑测试。您的测试应该验证行为(对象能够做什么,任务能够通过is公共API满足什么)我认为下面的Ian Cooper视频可以帮助您更好地理解如何处理此测试问题,以及如何避免编写与测试代码过于耦合的测试: