单元测试 测试私有方法
TDD的新手问了一些有趣的问题,最近有人问我:测试私有方法是不好的,但是为什么呢?
我们是怎么来到这里的?
如果您要测试私有方法,那么您做错了什么。 您无法从这里进入TDD必杀技,您必须回去。
一切都始于一个无害的小方法和一个无害的小方法。 它做了一点工作,做了一个不错的小单元测试,以验证它是否正确完成了任务。 世界一切正常。 然后,我不得不增加一点逻辑。 我为此编写了一个测试,更改了类,直到测试通过。 快乐的地方。 然后我开始重构。 我意识到我的小方法,因为它的测试用例很少,因此变得很复杂,因此我使用了提取方法重构和繁荣! 我有一个私人方法。
虽然提取时很简单,但又有一些极端的情况,并且这种私有方法演变成相当复杂的代码–现在我测试删除的一个级别:我正在测试外部方法的整体功能,该方法间接测试私有方法的行为。 在某个时候,我将遇到一个很难从外部进行测试的极端情况,如果我可以直接测试私有方法,那将变得非常容易。
不该做什么
不要使用让您测试私有方法的测试框架。 天哪,不。 为了所有人的爱,世界远离键盘。
该怎么做
这是测试对您说话的主要示例。 他们基本上是在对你喊 。 但是他们在说什么呢?
您的设计很臭!
如果您需要测试私有方法,那么您做错的是设计。 几乎可以肯定,您用私人方法确定的是全新的责任 。 如果您仔细考虑一下,可能与您的原始课程无关。 尽管您的原始班级可能需要重命名才能使其变得明显。 也可以 那是工作中的增量设计。
现在有个例子会有所帮助
假设我从投资组合类开始-它包含一堆资产,每个资产都有一个值。 因此,我可以实现Portfolio.GetValue()来告诉我它们全部值多少。 但是后来我开始处理诸如开盘价或收盘价之类的怪异情况。 我所说的价值是什么,现在可以卖给我什么? 也许需要进行一些外币兑换,或者要求提早退出的罚款条款,如何将所有这些因素考虑在内?
不久之后,GetValue()具有相当大的逻辑,我将其提取到GetSpotSalePrice(Asset)中。 这样一来,该方法就足够多了,需要进行测试,因此很明显我的设计很臭 。 我震耳欲聋的叮当声终于说服我将GetSpotSalePrice(Asset)提取到另一个类中,但这是一百万美元的问题: 哪一个 ?
不做什么–第2部分
为了喜欢SOLID,请不要将其放在AssetSalePriceCalculator或SalePriceManager中。 这是容易犯的第一大错误–您可以遵循TDD并忽略体面的OO设计,但最终还是会冒出一团糟。
NounVerber类始终是设计气味。 只是停止做。 现在。 我是认真的。 我在看着你。 我将搜寻您,并将您喂给AbstractSingletonProxyFactoryBean的食人魔。
那我该怎么办?
答案似乎很明显,但是对于开始做TDD和半体面设计的太多人来说,这根本不是显而易见的。 该方法需要转移到有责任感的课堂上 。 在我们的示例中,非常明显的是,这实际上是Asset上的一种方法–它甚至传入了一个。如果您的方法具有一个类参数并使用该类中的大量数据,则您可以打赌您的底价将使您羡慕不已。 整理生活,应用方法移动重构。 从此快乐地生活。
摘要
为什么不测试私有方法? 因为您要提问的事实意味着该方法不应该是私有的-这是需要测试的独立行为。 艰难的选择,即设计决策 ,是您坚持不懈的地方。
翻译自: https://www.javacodegeeks.com/2014/03/why-shouldnt-i-test-private-methods.html
单元测试 测试私有方法