我已经阅读了这篇关于如何测试私有方法的文章。我通常不测试它们,因为我总是认为只测试将从对象外部调用的公共方法更快。你测试私有方法吗?我应该一直测试它们吗?
当前回答
这显然与语言有关。在过去的c++中,我将测试类声明为友类。不幸的是,这需要您的生产代码了解测试类。
其他回答
绝对是的。这就是单元测试的要点,你测试单元。私有方法是一个单元。没有测试私有方法,TDD(测试驱动开发)是不可能的,
我认为单元测试是用来测试公共方法的。您的公共方法使用您的私有方法,因此它们也间接地接受测试。
我倾向于遵循Dave Thomas和Andy Hunt在他们的书《实用单元测试》中的建议:
一般来说,为了不破坏任何封装 测试(或者就像妈妈常说的,“不要暴露你的私处!”)。大多数 此时,您应该能够通过执行类的 公共方法。如果隐藏了重要的功能 在私人或受保护访问的背后,这可能是一个警告信号 还有一群人在里面挣扎着想出来。
但有时我无法阻止自己测试私有方法,因为它给了我一种安全感,我正在构建一个完全健壮的程序。
其中一个要点是
如果我们测试以确保逻辑的正确性,并且私有方法携带逻辑,那么我们应该测试它。不是吗?我们为什么要跳过这个呢?
基于方法的可见性编写测试是完全无关的想法。
相反
另一方面,在原始类之外调用私有方法是一个主要问题。在一些模拟工具中,模拟私有方法也有局限性。(例:5)
虽然有一些工具如Power Mock支持这一点,但这是一个危险的操作。原因是它需要破解JVM来实现这一点。
一种可以解决的方法是(如果您想为私有方法编写测试用例)
将这些私有方法声明为受保护的。但在某些情况下可能不方便。
“我应该测试私有方法吗?”的答案是“有时.......”。通常情况下,您应该针对类的接口进行测试。
其中一个原因是您不需要对一个特性进行双重覆盖。 另一个原因是,如果您更改了私有方法,则必须为它们更新每个测试,即使对象的接口根本没有更改。
这里有一个例子:
class Thing
def some_string
one + two
end
private
def one
'aaaa'
end
def two
'bbbb'
end
end
class RefactoredThing
def some_string
one + one_a + two + two_b
end
private
def one
'aa'
end
def one_a
'aa'
end
def two
'bb'
end
def two_b
'bb'
end
end
在RefactoredThing中,你现在有5个测试,其中2个你必须为重构而更新,但你的对象的功能实际上没有改变。所以让我们假设事情比这更复杂,你有一些方法来定义输出的顺序,比如:
def some_string_positioner
if some case
elsif other case
elsif other case
elsif other case
else one more case
end
end
这不应该由外部用户来运行,但是您的封装类可能太笨重了,无法一遍又一遍地运行这么多逻辑。在这种情况下,您可能更愿意将其提取到一个单独的类中,为该类提供一个接口并对其进行测试。
最后,假设你的主对象非常重,方法非常小你需要确保输出是正确的。你会想,“我必须测试这个私有方法!”也许你可以通过传入一些繁重的工作作为初始化参数使你的对象更轻?然后你可以放一些更轻的东西进去测试。
推荐文章
- 对于不可变集合上的非突变“add”方法,最好的名称是什么?
- foo到底是什么意思?
- 如何使用Jest测试对象键和值是否相等?
- 确定bash中是否存在一个函数
- foreach和map有区别吗?
- 使用Moq验证特定参数
- 如何为python模块的argparse部分编写测试?
- python中的assertEquals和assertEqual
- 如何使用“测试”包打印Go测试?
- 设计模式:工厂vs工厂方法vs抽象工厂
- 如何在IntelliJ中为整个项目配置“缩短命令行”方法
- 为什么处理排序数组比未排序数组慢?
- toBe(true) vs toBeTruthy() vs toBeTrue()
- 构造函数何时抛出异常是正确的?
- 使用Mockito测试抽象类