Java - 需要有关如何对此类进行单元测试的建议

时间:2016-04-09 18:50:26

标签: java unit-testing junit

在构建单元测试或测试用例时,我不是很有经验,现在我需要一些建议。我有这个课程,我打算制作,但我不确定它最好的单元测试方法是什么。我还没有写过课程,但它看起来像这样:

public class ClassName {

    private ArrayList<Order> sortedOrderList1 = new ArrayList<>();
    private ArrayList<Order> sortedOrderList2 = new ArrayList<>();

    public void method1(Order order) {
      //Modifies Order objects inside sortedOrderList1 or sortedOrderList2.
    }

    public method2(Order order) {
      //Modifies Order objects inside sortedOrderList1 or sortedOrderList1.
    }
}

列表中的Order个对象包含pricequantity。这些方法将进入列表并从quantity中减去列表末尾的某些Order对象,并删除quantity已达到0的对象。

现在的问题是我不知道测试这些方法的最佳方法是什么。在我的JUnit类中,我将无法访问private列表,并且这些方法本身没有返回值供我检查。测试这些方法的最佳实践方法是什么?

2 个答案:

答案 0 :(得分:1)

您应该为这两种公共方法创建单元测试。如果这些方法对订单对象进行更改,则它们作为参数传递,那么单元测试应该在该对象上有断言。您还应该检查sortedOrderLists的状态。

要抓住这些已排序的订单列表以检查它们,您会遇到一些问题。以下是三种可能的解决方案。

第一个选项,如果由于某种原因你不能或不想改变你的类实现。您将不得不使用反射来获取对这些私有字段的引用。

第二个选项是将这些字段的可见性更改为受保护。然后在同一个包中创建单元测试类。现在可以直接获取那些已排序的订单列表。

第三个也许是最好的选择是对这些字段使用依赖注入。依赖注入有许多不同的选项。你可以使用类似的CDI或Spring。但为了保持简单,你可以使用普通的java setter或构造函数注入。只是不要在课堂上新建这些列表。由于您注入了这些列表,现在它们甚至可以是私有的。您的单元测试类将创建列表并将其注入您正在测试的类中。现在您可以参考这些私有字段,并可以使用断言来检查它们。

构造函数注入的示例:

public class ClassName {

    private ArrayList<Order> sortedOrderList1;
    private ArrayList<Order> sortedOrderList2;

    public ClassName(ArrayList<Order> sortedOrderList1, ArrayList<Order> sortedOrderList2) {
        this.sortedOrderList1 = sortedOrderList1;
        this.sortedOrderList2 = sortedOrderList2;
    }

    public void method1(Order order) {
      //Modifies Order objects inside sortedOrderList1 or sortedOrderList2.
    }

    public method2(Order order) {
      //Modifies Order objects inside sortedOrderList1 or sortedOrderList1.
    }
}

单元测试示例:

import org.junit.Assert;

public class ClassNameTest {

    public void testMethod1() {
        ArrayList<Order> list1 = new ArrayList<>();
        ArrayList<Order> list2 = new ArrayList<>();
        Order order = new Order();
        ClassName testMe = new ClassName(list1, list2);
        testMe.method1(order);
        // Insert your assertions for example:
        Assert.assertTrue(list1.contains(order));
    }

}

答案 1 :(得分:1)

如果您所描述的课程没有其他任何内容,那么您也可以不对它进行单元测试,因为它没用。为了使您的代码有用,它必须返回值,更改状态或两者都可以。在您的示例中,您正在修改状态,因此您的测试需要验证状态更改是否已正确发生。现在你必须修改状态才能实现某些目标,即另一种方法返回该数据或者它被发送到某个地方 - 这个就是你对代码进行单元测试的方式。

<强>更新

根据OP提供的更多信息,有一种方法可以将订单打印到STDOUT。这符合我上面提到的副作用功能。在这种情况下,您可能需要提供STDOUT的抽象,您可以在测试中模拟/伪造,然后验证更新的订单是否正确地实现了这一目标。