纯粹的答案是私有方法被称为是有原因的! ;-)
转过头来:只给出一个(可公开访问的)接口的规范,在编写代码之前,您将如何布置您的测试计划?该接口描述了实现它的对象的预期行为;如果在该级别上无法测试,则说明设计有问题。
例如,如果我们是一家运输公司,我们可能有这些(伪编码)接口:
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 也是如此。
如果我们需要测试独立于CapitalAsset 和PeopleMover 通用合同的Bus 的某些内容,那么我们需要单独的总线测试。
如果特定的具体类具有如此复杂的公共方法,以至于 TDD 和/或 BDD 无法清晰地表达其预期行为,那么,这又是一个错误的线索。如果具体类中有私有的“帮助”方法,它们应该是有特定原因的;应该可以问“如果这个助手有缺陷,什么公共行为会受到影响(以及如何)?”
对于合法的、固有的复杂性(即来自问题域),一个类可能适合拥有负责特定概念的帮助器类的私有实例。在这种情况下,辅助类应该是可独立测试的。
一个好的经验法则是:
如果测试太复杂,那就太复杂了!