テストから始めます:-)
あなたのシステムは何をしますか?
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;
}
}
このコードを見ると問題ないように見えますが、Single Responsibility Principle (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
クラスに関するいくつかのテストを作成する可能性があります。
これで十分なスタートになることを願っています。たくさん残しました。:-)
それが役立つことを願っています!
ブランドン