我想测试 addElement 方法:
public class MyClass {
private List<Integer> ints = new ArrayList<>();
public void addElement(int element) {
ints.add(element);
}
}
我需要测试我的元素是否已添加。根据类隔离,我不能使用任何ArrayList方法来检查它。实际上我应该模拟我的arrayList。但是如果我嘲笑它并改变get()方法的行为以返回一些值,我就不能确定我的元素是否在该列表中。
如何测试?
答案 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%明确)。测试状态更改时,通常需要进行设置,执行某些操作,然后验证对象的状态是否按预期方式更改。在这些测试中,您通常不需要模拟(尽管您可能需要存根来提供测试数据)
在这种情况下,您将添加一个元素,然后调用一些其他方法来验证是否已添加该元素,例如尝试获取该元素,或验证存储元素的数量是否已增加。没有关于你的对象实际上做什么的更多细节,很难准确地指导你。
你的类中有一个私有数组列表的事实是一个实现细节,不应该是你的测试的焦点,否则如果你决定在将来更改其他东西的数组列表,你的测试可能需要更新
在测试交互时,您通常需要进行设置,执行一些操作,然后验证预期的交互是否发生。在这些测试中,您可能希望对正在测试的交互使用模拟。
例如,您可能希望检查您的类与另一个类(如记录器或数据库访问类)的交互是否以预期的方式发生。