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

Posted

技术标签:

【中文标题】我们可以为了方法级别的单元测试而将方法的访问说明符从私有更改为默认吗【英文标题】:Can we changed the access specifier of a method from private to default just for the sake of method level unit testing 【发布时间】:2021-07-10 04:01:48 【问题描述】:

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

【问题讨论】:

单元测试应该针对您单元的 API。如果该 API 实际上是包私有 API,那么您也应该对其进行测试 - 限制 API 的原因有很多 - 例如实用程序类。但是提升一个内部方法只是为了测试它的味道是糟糕的设计,一个不是为测试而设计的类。在旧代码中可接受,在新代码中不可接受。 【参考方案1】:

'default',即没有修饰符,在 Java 中意味着 package private。只有同一个包中的类可以访问它。有时需要在与该类的其余部分分开的单元测试中测试该类的私有使用的内部方法,以便通过清晰、简洁和简单的测试覆盖所有代码路径。当您这样做时(结果是更清晰的测试代码,可以更轻松地维护),可以将该方法标记为包私有。

This 并不是一个罕见的策略。因为唯一可以使用此方法的类必须位于同一个包中,所以您仍然可以充分控制它的使用。

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

请注意,在某些情况下,测试私有方法的需要可能意味着需要将类的该部分分解为一个单独的类。 This discussion 显示了从 strict OOP adherence 到 pragmatism 的一些常见观点。您通常可以拆分该方法并使其成为适当的公共静态实用程序,但这并不总是有意义,也不一定会使代码更易于维护。

【讨论】:

【参考方案2】:

UnitTests不是关于测试代码,它们是关于测试public observable 行为,即:返回值与依赖关系的通信

Public observable 不一定暗示public 方法,但通常是这样。我们只是测试其他代码在使用当前单元作为依赖项时会调用的方法。

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

请记住,unit 不连接到 classmethod。 它甚至可能是作为“入口点”的单个类后面的一组类。 一个单元是所有可能出于相同(非技术)原因而更改的代码,即业务需求的更改。

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

【讨论】:

以上是关于我们可以为了方法级别的单元测试而将方法的访问说明符从私有更改为默认吗的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之模式方法模式

如何在 TestNG 单元测试类中分配类级别数据

我有啥方法可以按表级别限制对 Redshift 外部模式的访问?

单元测试数据访问层 - 测试更新方法?

单元测试

单元测试概述