单元测试私有方法是一种好的做法吗?

单元测试私有方法是一种好的做法吗?

问题描述:

我想知道单元测试私有方法是否是一种好的做法?单元测试私有方法是一种好的做法吗?

通常只有公共接口应该被测试。

不过,我已经发现了复杂的计算,它调用吨不同的私有方法时,更容易进行单元测试第一的私有方法,然后进行了公共接口方法的简单测试。

作为例子,让我们假设你有一个音频播放器,你有功能:

void play(){ ... } 
void pause(){ ... } 
void seek(time t) 
{ 
    //All Private methods 
    checkIfValidTimeRange(...); 
    moveToFilePos(...);  
    fillBuffers(...);  
} 

通常我会编写单元测试:checkIfValidTimeRange(...)moveToFilePos(...)fillBuffers(...)

但我不确定如果这样做是好的做法。

+2

做什么是有道理的..如果你的私人方法很复杂,为什么不测试它们? – 2012-02-08 23:02:16

这是不是一个好的做法(但这并不意味着你不应该这样做),如果可能的话,你想避免它。测试私人方法通常意味着您的design could be better。让我们快速浏览一下您的播放器例如:

  • moveToFilePos:听起来更像的东西做的I \ O操作的责任,而不是音乐播放器的
  • fillBuffers:更多的是内存管理的工作,而不是音乐播放器
  • checkIfValidTimeRange:再次,也许可以被移出玩家的范围,一些简单的验证类(好像这一个可能是藏汉其他地方有用)

此刻你音乐播放器没有I/O,内存管理和其他什么。这一切是否真的在其职责范围内?

+0

这个例子只是为了展示一个简单的演示。但让我说我创建MusicFileIO类和MusicFileBuffer类来检查。我应该让这些课程在音乐播放器课程内部进行吗? (因为我不想暴露他们的存在给用户)。但是,如果我让他们成为内部和私人的,我是否一开始就不回到我的问题? – Anton 2012-02-09 00:00:31

+1

@安顿:只要他们得到适当的测试,那么这些新课程所暴露的内容是多么的无关紧要。我们正在从这个真正的问题中走出来 - 测试私有方法并不坏,因为*方法是私有方法*,但是因为它通常意味着*糟糕的设计*。当您更改'fillBuffer'(*“现在缓冲区来自其他地方!” - 匿名客户端*)时,您不希望发现自己处于某种情况下。现在没什么意义了,以后再也没有意义了。 – 2012-02-09 14:36:25

+0

仍然。未经测试的代码变成“遗留”代码(参见[使用遗留代码有效工作](http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052))。 因此,如果公共接口的真实复杂性是完全覆盖它(例如门面)是不可行的,那么测试私有方法是imho是两个恶意中较小的一个。 – Txangel 2013-05-31 13:14:14

恕我直言,这是一个非常不错的主意,我做这一切的时候。我通常会创建一个辅助类,这使得私有方法accessable并测试它..

通常它更容易测试私有方法,因为他们做的非常具体的东西。另一方面,你可能有一个很大的公开方法,这有点难以测试。所以它肯定简化了单元测试。

如果你的私有方法十分复杂,需要测试,你可能错过了一些类,其中的私有方法是把公共。

你当然可以测试私有方法,但你应该把需要做它作为一个提示有什么不对您的设计。

你的代码库的哪个部分是你的私有方法依赖? 如果有人改变了你所依靠的方法之一,从而打破了你的方法,是否值得了解它? 测试不仅用于检查您的方法是否应该如其行为,而且还用于检查代码库其他部分中的更改是否不会破坏您的方法。

所以,除非你的方法只使用语言的基本结构,测试一下吧!