1

目標: 典型的なエンタープライズ Java 環境で TDD をテストする。

環境 :

使用したフレームワーク (やり過ぎですが、プロジェクトベースの学習を実践しています) :

  • DAO : 休止状態
  • 春の IOC
  • フロント : Spring MVC + Twitter Boostrap (可能な場合)
  • TDD : JUnit
  • DB : PostgreSQL

私のプロジェクトは、フリーランサーが請求書を作成、編集、印刷/顧客に送信するのに役立つシンプルな請求システムです。

プロジェクトを作成して構成したら、どこから始めればよいかわかりません。私の最初の機能は、一意の番号とタイトルを持つ請求書を作成することだとしましょう。

質問: 最初に何をテストすればよいですか?

  • 一意のシリアル番号を生成する createBill(String title) メソッドを含むドメイン層? DBレイヤーをモックします。
  • 最初にUI、サービスレイヤーをモックしますか? やり方がわかりません。

ご回答ありがとうございます。

乾杯

4

1 に答える 1

4

テストから始めます:-)

あなたのシステムは何をしますか?

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クラスに関するいくつかのテストを作成する可能性があります。

これで十分なスタートになることを願っています。たくさん残しました。:-)

それが役立つことを願っています!

ブランドン

于 2012-10-05T21:23:32.127 に答える