我们是否可以仅仅为了方法级单元测试而将方法的访问说明符从私有更改为默认值

Can we changed the access specifier of a method from private to default just for the sake of method level unit testing

提问人:Sampath Kumar 提问时间:4/15/2021 更新时间:4/17/2021 访问量:613

问:

我可以找到很多关于为什么一种方法不应该公开的问题/答案。但我在 Java 中找不到任何特定于“默认”的内容。

java 单元测试 OOP 封装访问 说明符

评论

2赞 Boris the Spider 4/15/2021
单元测试应针对单元的 API。如果该 API 实际上是一个包私有 API,那么你也应该测试它 - API 受到限制的原因有很多 - 例如实用程序类。但是,仅仅为了测试而提升内部方法,这听起来像是糟糕的设计,而这个类不是为测试而设计的。在旧代码中可接受,在新代码中不可接受。

答:

1赞 JeroenHoek 4/15/2021 #1

'default',即没有修饰符,在 Java 中表示包私有。只有同一包中的类才能访问它。有时,希望在与该类的其余部分分开的单元测试中测试用于该类的私人使用的内部方法,以便通过清晰、简洁和简单的测试涵盖所有代码路径。执行此操作时(结果是可以更轻松地维护的更干净的测试代码),可以将该方法标记为包私有。

这种策略并不少见。由于唯一可以使用此方法的类必须驻留在同一个包中,因此您仍然可以对其使用进行充分的控制。

就我个人而言,我建议只对不依赖于其父类状态的实用程序方法执行此操作。它也是在抽象类中测试静态方法的一种非常有用的技术。static

请注意,在某些情况下,测试私有方法的需要可能表明需要将类的这一部分分解为一个单独的类。这个讨论显示了一些共同的立场,从严格的OOP遵守实用主义。你通常有可能打破该方法,使其成为一个适当的公共静态实用程序,但这并不总是有意义的,它不一定会导致更容易维护的代码。

1赞 Timothy Truckle 4/17/2021 #2

UnitTests 不是关于测试代码,而是关于测试公共可观察行为,即:返回值与依赖项的通信

Public Observable 并不一定意味着方法,但通常是。我们只需测试其他代码在使用当前单元作为依赖项时将调用的方法。public

非公共方法(不应由其他代码调用)是有助于单元行为的实现详细信息。因此,它们隐含地是睾丸。

请记住,单元未连接到方法。 它甚至可能是充当“入口点”的单个类后面的一组类。 单元是可能由于相同的(非技术)原因(业务需求的变化)而更改的所有代码。

这里的重点是,实现细节可能会改变,而所需的行为(以及 UnitTest)不会改变。我们进行此类更改是为了改进代码设计(解决代码重复问题、应用设计模式等)。我们称之为重构(这是测试驱动开发微周期的第三阶段)。这样的重构正是我们最需要 UnitTest 的时候,因为当我们不更改它们时,它们可以保证测试代码的所需行为仍然存在。