有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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);
    }
}

如果我首先开发了失败案例,并且为每个测试方法开发了一个模拟,在模拟之后开发了一个实现,那么这是一种测试驱动的开发方法吗

问候,


共 (3) 个答案

  1. # 1 楼答案

    只要有测试,就不能查看代码,看它是否使用TDD开发。TDD周期如下所示:

    1. 写测试
    2. 让它过去
    3. 重构

    一件微妙的事情是,除非是为了通过失败的测试,否则您可能不会添加任何新功能

    使用的模拟数量无关紧要

  2. # 2 楼答案

    虽然人们可能会对它施加其他条件,但通常情况下,如果您在编写代码之前和编写代码时编写测试,它可能是测试驱动的。您通常会先提出失败的测试,然后编写代码使其通过

  3. # 3 楼答案

    谁在调用该方法,例如successAllowedOrder()、SuccessPartialLowdOrder()、successDeniedOrder()?因为测试用例通常没有参数

    通常,应用TDD编写的单元测试遵循triple A pattern

    • 安排
    • Act
    • Assert

    还有fixture,即通过setup()和tearDown()方法执行、创建和清理测试的环境。夹具对于同一类中的所有测试都是通用的

    对于您的产品类别,这将提供以下内容:

    public class TestOrder extends TestCase
    {
        // assume the fixtures creates the Product instances used for the tests here
    
        void TestValidOrder() 
        {
          // arrange - create an order
          // act - do something on the order - could be empty if testing the creation
          // assert - test the status of the order
        } 
    

    }

    设计要点:为什么计算allowedQuantity和requiredQuantity的循环不属于Order类

    看看bowling game episode,这真的是一个很棒的TDD教程。 最后,您可以在不使用模拟对象的情况下执行TDD