java中的单元测试私有和静态方法

Posted

技术标签:

【中文标题】java中的单元测试私有和静态方法【英文标题】:Unit test private and static methods in java 【发布时间】:2018-02-22 17:56:34 【问题描述】:

我正在为我的一个应用程序编写单元测试,作为一种好的做法,我尝试使我的类中的所有方法尽可能私有,因此我最终可能会得到包含大部分私有方法的类,很少有公共方法,有时还有一些调用静态方法(我的其他类或一些 TextUtils 等)

我想知道如何测试我所有试图仅依赖 Mockito 和 JUnit 的类,因为 Robolectric 和 Powermockito 似乎扩展了单元测试中应该做的事情的界限。我应该忽略所有私有和静态方法以及偶然调用一些静态或私有方法的公共方法吗?还是怎么做?

【问题讨论】:

这是两个截然不同的问题。通常,私有成员应该通过公共接口间接测试,而静态方法通常是可独立测试的。 【参考方案1】:

注意:这只是一般信息,因为您的问题不提供评论代码。

由于私有方法通常不能在类之外访问(反射完全是另一回事),并且通常在那里为您的公共和受保护方法提供功能,因此您的单元测试只需要测试您的公共和受保护方法。如果你仔细选择你的测试数据,你应该能够练习大部分/所有代码。

您可以使用 Mockito 模拟被测类所需的任何依赖项。您使用期望(Mockito.when(...).thenReturn(...)Mockito.verify(mockedClass).method(...))来模拟外部功能或检查被测类是否按预期进行传出调用。

您可以使用断言来检查被测试的方法是否返回适当的值。

但是请记住,在您第一次尝试更改被测类的内部实现时,具有高代码覆盖率的详细单元测试很可能会中断。这是一种平衡行为,您需要找到合适的覆盖范围,同时尽量减少测试的脆弱性。

【讨论】:

谢谢你的回答,我评论了上面的答案为什么我认为跳过直接私有方法测试可能是错误的【参考方案2】:

您正在测试的类中的所有私有方法都应该由一些公共/受保护/包私有方法调用;否则它们是未使用的代码。因此,只需集中精力测试这个对您的应用程序的“客户端代码”可见的公共 API。内部(私有方法)将作为副作用进行测试/覆盖,因为它们实际上实现了 API 指定的公共合同。

直接测试实现细节(私有方法)会使测试更难维护,被测代码更难重构。

【讨论】:

感谢您的回答。我实际上想到了这一点,但在我的脑海中听起来有些错误,因为如果我有一个公共方法也调用私有方法,并且我测试前者以捕获它们,那感觉我不再测试“单元”而是“合奏” 单元测试中的“单元”并不总是那么容易定义。但总的来说,我认为从长远来看,如果您专注于测试类的公共接口并很好地封装实现细节,那么事情会变得更容易。如果您认为私有方法正在做您想专门测试的事情,那么这可能意味着该逻辑应该在其自己的类中建模,然后可以(公开)单独进行单元测试。 @kioli "感觉我测试的不是"单元"而是"合奏"" -这里的问题是什么是单元我喜欢 Roy Osherove 的定义:一个单元是一堆有相同理由改变的代码。这意味着一个unit 可以是单个方法或几个类。 非常感谢,我将尝试在我已经进行的所有测试中采用这种方法

以上是关于java中的单元测试私有和静态方法的主要内容,如果未能解决你的问题,请参考以下文章

Java单元测试对私有方法测试

Java单元测试对私有方法测试

java java中的单元测试私有构造函数

PowerMock单元测试

如何在 Typescript 中对私有方法进行单元测试

如何在Typescript中对私有方法进行单元测试