从测试开始:-)
你的系统是做什么的?
public class BillingSystemTest {
@Test
public void generatesBills() {
Bill bill = new BillingSystem().generate()
assertNotNull(bill)
}
}
第一次测试完成!
让它通过,继续下一个测试......
@Test
public void generatesAnInvoiceNumberForEachBill() {
Bill bill = new BillingSystem().generate()
assertEquals(1, bill.getNumber())
}
// ...and the next
@Test
public void generatesUniqueInvoiceNumbersForEachBill() {
BillingSystem bs = new BillingSystem()
assertEquals(1, bs.generate().getNumber())
assertEquals(2, bs.generate().getNumber())
}
@Test
public void generatesAnInvoiceSubjectWhenNoneIsSpecified() {
Bill bill = new BillingSystem().generate()
assertEquals("Invoice #1 from ACME Corp.", bill.getSubject())
}
@Test
public void allowsForCustomSubjectsOnBills() {
Bill bill = new BillingSystem().generate("Custom subject")
assertEquals("Custom subject", bill.getSubject())
}
我显然已经跳过了这里的重构步骤,但是现在您已经有了测试以及随之而来的代码,您需要对其进行评估以获得更多机会。我想象代码看起来像这样。
public class BillingSystem {
private nextInvoiceNumber = 1;
public Bill generate() {
return generate("Invoice #" + nextInvoiceNumber + " from ACME Corp.");
}
public Bill generate(String subject) {
Bill bill = new Bill(nextInvoiceNumber, subject)
nextInvoiceNumber++
return bill;
}
}
看这段代码,似乎没问题,但可能违反了单一职责原则(SRP)。这里BillingSystem
生成账单以及管理发票编号。这是一个重构的机会。重构后,您的设计可能如下所示:
public class BillingSystem {
private InvoiceNumbering invoiceNumbering = new InvoiceNumbering()
public Bill generate() {
return generate("Invoice #" + invoiceNumbering.peekNext() + " from ACME Corp.");
}
public Bill generate(String subject) {
Bill bill = new Bill(invoiceNumbering.generateNext(), subject)
nextInvoiceNumber++
return bill;
}
}
你的设计更好,你的测试都通过了。接下来要做的是重构测试以从中删除实现细节。他们最终可能看起来像:
@Test
public void generatesBills() {
Bill bill = new BillingSystem().generate()
assertNotNull(bill)
}
@Test
public void generatesAnInvoiceNumberForEachBill() {
// Using hand rolled mocks
MockInvoiceNumbering in = new MockInvoiceNumbering()
in.generateNextShouldReturn(4)
Bill bill = new BillingSystem(in).generate()
assertEquals(4, bill.getNumber())
}
@Test
public void generatesUniqueInvoiceNumbersForEachBill() {
MockInvoiceNumbering in = new MockInvoiceNumbering()
BillingSystem bs = new BillingSystem(in)
bs.generate();
bs.generate();
assertEquals(2, in.numberOfTimesGenerateNextWasCalled)
}
@Test
public void generatesAnInvoiceSubjectWhenNoneIsSpecified() {
Bill bill = new BillingSystem().generate()
assertEquals("Invoice #1 from ACME Corp.", bill.getSubject())
}
@Test
public void allowsForCustomSubjectsOnBills() {
Bill bill = new BillingSystem().generate("Custom subject")
assertEquals("Custom subject", bill.getSubject())
}
作为此重构的一部分,您可能会围绕您的InvoiceNumbering
类创建一些测试。
希望这是一个足够的开始。留下了很多东西。:-)
希望有帮助!
布兰登