纯粹的答案是私有方法被称为是有原因的!;-)
把问题转过来:只给定一个(可公开访问的)接口的规范,在编写代码之前你将如何布置你的测试计划?该接口描述了实现它的对象的预期行为;如果在该级别上无法测试,则说明设计有问题。
例如,如果我们是一家运输公司,我们可能有这些(伪编码)接口:
CapitalAsset {
Money getPurchaseCost();
Money getCurrentValue();
Date whenPurchased();
...
}
PeopleMover {
Weight getVehicleWeight();
int getPersonCapacitly();
int getMilesOnFullTank();
Money getCostPerPersonMileFullyLoaded(Money fuelPerGallon);
...
}
并且可能有包括这些的类:
Bus implements CapitalAsset, PeopleMover {
Account getCurrentAdvertiser() {...}
boolean getArticulated() {...}
...
}
Computer implements CapitalAsset {
boolean isRacked() {...}
...
}
Van implements CapitalAsset, PeopleMover {
boolean getWheelchairEnabled() {...}
...
}
在设计CapitalAsset
概念和界面时,我们应该与财务人员就任何实例的CapitalAsset
行为方式达成一致。我们将仅CapitalAsset
根据该协议编写针对该协议的测试;我们应该能够在 、 等上运行这些测试,而不依赖于涉及哪个具体类。同样对于.Bus
Computer
Van
PeopleMover
如果我们需要测试与 aBus
无关的东西CapitalAsset
,PeopleMover
那么我们需要单独的总线测试。
如果一个特定的具体类具有如此复杂的公共方法,以至于 TDD 和/或 BDD 无法清晰地表达它们的预期行为,那么这又是一个错误的线索。如果具体类中有私有的“帮助器”方法,它们应该出于特定原因而存在;应该可以问“如果这个助手有缺陷,什么公共行为会受到影响(以及如何)?”
对于合法的、固有的复杂性(即来自问题域),一个类可能适合拥有对特定概念负责的辅助类的私有实例。在这种情况下,辅助类应该是可自行测试的。
一个好的经验法则是:
如果测试太复杂,那就太复杂了!