如何测试使用junit将元素添加到arraylist

时间:2015-05-28 18:41:49

标签: java unit-testing arraylist junit mocking


我想测试 addElement 方法:

public class MyClass {
    private List<Integer> ints = new ArrayList<>();

    public void addElement(int element) {
        ints.add(element);
    }
}

我需要测试我的元素是否已添加。根据类隔离,我不能使用任何ArrayList方法来检查它。实际上我应该模拟我的arrayList。但是如果我嘲笑它并改变get()方法的行为以返回一些值,我就不能确定我的元素是否在该列表中。

如何测试?

4 个答案:

答案 0 :(得分:2)

assertEquals(intsPreviousSize + 1, ints.size()),并为ints ArrayList提供了一个getter方法。如果你没有吸气剂,那么你可以使用反射,如果你不能这样做,那么我认为你不能。

答案 1 :(得分:2)

在精神层面而不是代码层面,你想要测试什么?

听起来您正在尝试验证MyClass.addElement(int)确实添加了一个元素。

MyClass还有哪些其他公共方法?如果它没有,那么如果addElement(int)实际添加了元素,它就不会真正重要,因为两个可能的情况之间没有外在差异。

我将假设,MyClass有一些其他方法的行为会有所不同,具体取决于ints的内容,您可以使用这些方法确定addElement(int)是否ints做了预期的事。

例如,如果addElement(int)有吸气剂,您只需在ints之前和之后调用它,并比较这两个点的列表内容。

或者,如果有一个总结addElement(int)中的值的方法,你可以调用它并比较调用ch_1q2ew34sdfsadf334f43tf4y6y, or ch_1343ggrgr or asdfasdf2234234 之前和之后返回的值并确保差值等于你的int加入。

答案 2 :(得分:0)

我建议创建一个MyClass的子类,它有一些public方法来检索ArrayList(或列表中的特定元素)。如果要从子类访问它,ints对象还需要将其访问级别更改为protected。如果您希望它更紧凑,您可以使用默认范围,并要求您的新类与MyClass位于同一个包中。我以前做过这个,并且认为能够对代码进行单元测试是合理的成本。

这样就会测试父类,但是您可以使用子类从测试中检索信息。

例如:

public class MyClass {
    protected List<Integer> ints = new ArrayList<>();
    ...
}

public class MyClassChild extends MyClass {
    public List<Integer> getInts() {
        return ints;
    }
}

// Test code
MyClassChild myClass = new MyClassChild();
myClass.addElement(42);
myclass.getInts().size() == 1;

如果所有其他方法都失败了,你可以依靠反射来检索对象,但这更麻烦(在我看来)。

答案 3 :(得分:0)

关注您要测试的行为。调用MyClass后,addElement以什么外部可测试的方式更改?这应该是你测试的重点。

测试通常分为两类。

  • 测试状态更改
  • 测试互动

在这种情况下,您似乎正在测试状态更改(尽管从您的缩减示例中并未100%明确)。测试状态更改时,通常需要进行设置,执行某些操作,然后验证对象的状态是否按预期方式更改。在这些测试中,您通常不需要模拟(尽管您可能需要存根来提供测试数据)

在这种情况下,您将添加一个元素,然后调用一些其他方法来验证是否已添加该元素,例如尝试获取该元素,或验证存储元素的数量是否已增加。没有关于你的对象实际上做什么的更多细节,很难准确地指导你。

你的类中有一个私有数组列表的事实是一个实现细节,不应该是你的测试的焦点,否则如果你决定在将来更改其他东西的数组列表,你的测试可能需要更新

在测试交互时,您通常需要进行设置,执行一些操作,然后验证预期的交互是否发生。在这些测试中,您可能希望对正在测试的交互使用模拟。

例如,您可能希望检查您的类与另一个类(如记录器或数据库访问类)的交互是否以预期的方式发生。