java是一种测试驱动的开发方法吗?
假设以下模型
public class Product {
private Integer requiredQuantity;
private Integer allowedQuantity;
// getters and setters
}
public class Order {
public void allowsOrder(List<Product> productList) throws AppException {
Integer allowedQuantity = 0;
Integer requiredQuantity = 0;
for(Product product: productList) {
if(product.getAllowedQuantity().compareTo().product.getRequiredQuantity() > 0)
throw new AllowedQuantityIsGreaterThanRequiredQuantity();
allowedQuantity += product.getAllowedQuantity();
requiredQuantity += product.getRequiredQuantity();
}
switch(allowedQuantity.compareTo(requiredQuantity)) {
case 0:
setOrderStatus(OrderStatus.ALLOWED);
break;
case -1:
if(allowedQuantity.equals(0))
setOrderStatus(OrderStatus.DENIED);
else
setOrderStatus(OrderStatus.PARTIALLY_ALLOWED);
break;
}
}
}
因此,我(在编写上述代码之前)开发了一个测试驱动开发,根据:
obs:对于每个测试方法,数据提供者(通过使用TestNG)提供参数
public void successAllowedOrder(List<Product> productList, Order beforeAllowingOrderMock, Order afterAllowingOrderMock) {
Integer allowedQuantity = 0;
Integer requiredQuantity = 0;
for(Product product: productList) {
allowedQuantity += product.getAllowedQuantity();
requiredQuantity += product.getRequiredQuantity();
}
assertEquals(allowedQuantity, requiredQuantity);
assertNull(beforeAllowingOrderMock.getOrderStatus());
assertEquals(OrderStatus.ALLOWED, afterAllowingOrderMock.getOrderStatus());
// beforeAllowingOrderMock is now a implementation
beforeAllowingOrderMock = new Order();
beforeAllowingOrderMock.allowsOrder(productList);
assertNotNull(beforeAllowingOrderMock.getOrderStatus());
assertEquals(beforeAllowingOrderMock.getOrderStatus(), afterAllowingOrderMock.getOrderStatus());
}
public void successPartiallyAllowedOrder(List<Product> productList, Order beforeAllowingOrderMock, Order afterAllowingOrderMock) {
Integer allowedQuantity = 0;
Integer requiredQuantity = 0;
for(Product product: productList) {
allowedQuantity += product.getAllowedQuantity();
requiredQuantity += product.getRequiredQuantity();
}
assertTrue(requiredQuantity > allowedQuantity);
assertNull(beforeAllowingOrderMock.getOrderStatus());
assertEquals(OrderStatus.PARTIALLY_ALLOWED, afterAllowingOrderMock.getOrderStatus());
// beforeAllowingOrderMock is now a implementation
beforeAllowingOrderMock = new Order();
beforeAllowingOrderMock.allowsOrder(productList);
assertNotNull(beforeAllowingOrderMock.getOrderStatus());
assertEquals(beforeAllowingOrderMock.getOrderStatus(), afterAllowingOrderMock.getOrderStatus());
}
public void successDeniedOrder(List<Product> productList, Order beforeAllowingOrderMock, Order afterAllowingOrderMock) {
Integer allowedQuantity = 0;
Integer requiredQuantity = 0;
for(Product product: productList) {
allowedQuantity += product.getAllowedQuantity();
requiredQuantity += product.getRequiredQuantity();
}
assertTrue(allowedQuantity == 0);
assertNull(beforeAllowingOrderMock.getOrderStatus());
assertEquals(OrderStatus.DENIED, afterAllowingOrderMock.getOrderStatus());
// beforeAllowingOrderMock is now a implementation
beforeAllowingOrderMock = new Order();
beforeAllowingOrderMock.allowsOrder(productList);
assertNotNull(beforeAllowingOrderMock.getOrderStatus());
assertEquals(beforeAllowingOrderMock.getOrderStatus(), afterAllowingOrderMock.getOrderStatus());
}
public void failureAllowedQuantityIsGreaterThanRequiredQuantity(List<Product> productList, Order beforeAllowingOrderMock) {
Integer allowedQuantity = 0;
Integer requiredQuantity = 0;
for(Product product: productList) {
allowedQuantity += product.getAllowedQuantity();
requiredQuantity += product.getRequiredQuantity();
}
assertTrue(allowedQuantity > requiredQuantity);
try {
beforeAllowingOrderMock.allowsOrder(productList);
} catch(Exception e) {
assertTrue(e instanceof AllowedQuantityIsGreaterThanRequiredQuantity);
}
// beforeAllowingOrderMock is now a implementation
beforeAllowingOrderMock = new Order();
try {
beforeAllowingOrderMock.allowsOrder(productList);
} catch(Exception e) {
assertTrue(e instanceof AllowedQuantityIsGreaterThanRequiredQuantity);
}
}
如果我首先开发了失败案例,并且为每个测试方法开发了一个模拟,在模拟之后开发了一个实现,那么这是一种测试驱动的开发方法吗
问候,
# 1 楼答案
只要有测试,就不能查看代码,看它是否使用TDD开发。TDD周期如下所示:
一件微妙的事情是,除非是为了通过失败的测试,否则您可能不会添加任何新功能
使用的模拟数量无关紧要
# 2 楼答案
虽然人们可能会对它施加其他条件,但通常情况下,如果您在编写代码之前和编写代码时编写测试,它可能是测试驱动的。您通常会先提出失败的测试,然后编写代码使其通过
# 3 楼答案
谁在调用该方法,例如successAllowedOrder()、SuccessPartialLowdOrder()、successDeniedOrder()?因为测试用例通常没有参数
通常,应用TDD编写的单元测试遵循triple A pattern:
还有fixture,即通过setup()和tearDown()方法执行、创建和清理测试的环境。夹具对于同一类中的所有测试都是通用的
对于您的产品类别,这将提供以下内容:
}
设计要点:为什么计算allowedQuantity和requiredQuantity的循环不属于Order类
看看bowling game episode,这真的是一个很棒的TDD教程。 最后,您可以在不使用模拟对象的情况下执行TDD