在这些条件下,伪造一个RGHConnection对象最好的方法是对RGHConnection类应用接口提取。如果你手头一个支持重构的工具,那么它很可能也会支持接口提取方法。我们来看一下接口提取后的情况:
<interface> IRGHConnection +connect() + disconnect() +RFDIReportFor(id:int):RFDIReport +ACTIOReportFor(customerID:int) ACTIOReport |
由于retry()和fromPacket()不属于业务相关方法因此只需要在实现类中增加这两个方法,至此我们可以轻松的构建出一个FackeConnection类,并使它能够提供我们所需要的反馈信息,然后将这个伪造的对象用在测试中:
public class FakeConnection implements IRGHConnection { public RFDIReport report; public void connect() {} public void disconnnect(){} public RFDIReport RFDReportFor(int id) {return report;} public ACTIOReport ACTIOReportFor(int customerID) {return null;} } |
下面我们来写测试
void testNoSuccess()throws Exception{ CreditMaster master = new CreditMaster("crm2.mas",true); IRGHConnection connection = new FakeConnection(); CreditValidator validator = new CreditValidator(connection,master,"a"); connection.report = new RFDReport(....); Certificate result = validator.validatorCustomer(new Customer(...)); assertEquals(Certificate.VALID,result.getStatus()); } |
虽然FakeConnection类看起来有点奇怪:它的方法要么是空的要么就简单的返回null。这种情形并不常见。更糟的是,它有一个任何人都可以看到的并随意设置的公共变量。这样一个类似似乎违反了所有的良好准则。但你要看到,实际上并非如此。对于一个用来使得测试可行的类,规则是所不同的。FakeConnection中的代码并非产品代码。它永远也不属于最终投入运行的应用,而只是为了测试工具和测试而诞生。
有了这个fake类我们接下去便可以做更多的相关测试。这就是提高代码可测试性和遇到教难构造的的类的时候所采取的一种方法。若代码设计阶段就将RGHConnection设计为接口,那么在后面的测试中会是测试更加方便,使代码在后期的重构也会更加方便。