目标:在典型的企业Java环境中测试TDD。
背景:
使用的框架(即使它过度杀伤,我练习project based learning):
我的项目是一个简单的结算系统,可以帮助自由职业者创建,编辑和打印/向客户发送账单。
创建和配置项目后,我不知道从哪里开始。 假设我的第一个功能是创建一个具有唯一编号和标题的帐单。
问题:我应该先测试什么?
提前感谢您的回答,
干杯
答案 0 :(得分: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;
}
}
查看此代码,似乎没问题,但可能违反单一责任原则(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
类创建一些测试。
希望这是一个开始。留下了很多。 : - )
希望有所帮助!
布兰登