我是单位测试的新手,并试图学习正确的风格。我喜欢设置我正在测试的对象,以便我可以测试它,就像它正在使用而不是仅测试新构造的对象。我无法测试从空的对象中删除东西,因为构造时会有很多对象。
以下是一个测试ObservedList的示例,ListListener是一个被模拟的必要类。
public final class ObservedListTest {
private ListListener<Integer> listener;
private ObservedList<Integer> list;
@BeforeMethod public void setup() {
listener = mock(ListListener.class);
list = new ObservedList<Integer>(listener);
list.addAll(Arrays.asList(1,2,3));
reset(listener);
}
@Test public void addFirst() {
list.add(0, -1);
verify(listener).listEdited(list, 0, 1, Collections.<Integer>emptyList());
verifyNoMoreInteractions(listener);
}
@Test void addAtEnd() {
list.add(9);
verify(listener).listEdited(list, 3, 4, Collections.<Integer>emptyList());
verifyNoMoreInteractions(listener);
}
@Test void removeMiddle() {
list.remove(Integer.valueOf(2));
verify(listener).listEdited(list, 1, 1, Collections.singletonList(2));
verifyNoMoreInteractions(listener);
}
}
作为一个新手,这似乎对我有用,但我知道这是不好的做法,因为它使用reset
方法。我打电话给reset
因为我不希望实际测试因设置中发生的交互而混淆。
reset
的javadoc甚至没有告诉你该方法的作用,因为它太忙于告诉你不应该使用它。通常我只是采用这个建议,并通过删除我的reset
方法并调整我的测试看起来更像这样来避免setup
:
@Test void removeMiddle() {
listener = mock(ListListener.class);
list = new ObservedList<Integer>(listener);
list.addAll(Arrays.asList(1,2,3));
list.remove(Integer.valueOf(2));
InOrder inOrder = inOrder(listener);
inOrder.verify(listener).listEdited(list, 0, 3,
Collections.<Integer>emptyList());
inOrder.verify(listener).listEdited(list, 1, 1,
Collections.singletonList(2));
verifyNoMoreInteractions(listener);
}
这个也似乎对我有用。问题是reset
方法的文档说:
请考虑编写简单,小巧且专注的内容,而不是重置() 测试方法超过冗长,过度指定的测试。
我尊重Mockito旨在鼓励单元测试中的好风格,我想从中学习,但我很难理清它试图发送给我的信息。当我从测试中删除reset
时,我的测试得到复杂,更长和更少关注,所以显然我正在做错。
做得对的样子是什么样的?
答案 0 :(得分:2)
删除reset
。删除verifyNoMoreInteractions
。问题解决了。您的测试更简单,更短,更专注。
答案 1 :(得分:1)
Mockito 2.1添加了clearInvocations
方法,可以这样使用:
public final class ObservedListTest {
private ListListener<Integer> listener;
private ObservedList<Integer> list;
@BeforeMethod public void setup() {
listener = mock(ListListener.class);
list = new ObservedList<Integer>(listener);
list.addAll(Arrays.asList(1,2,3));
clearInvocations(listener);
}
@Test public void addFirst() {
list.add(0, -1);
verify(listener, only()).listEdited(list, 0, 1, Collections.<Integer>emptyList());
}
@Test void addAtEnd() {
list.add(9);
verify(listener, only()).listEdited(list, 3, 4, Collections.<Integer>emptyList());
}
@Test void removeMiddle() {
list.remove(Integer.valueOf(2));
verify(listener, only()).listEdited(list, 1, 1, Collections.singletonList(2));
}
}
请注意,clearInvocations
javadoc还声明:
尽量避免使用此方法。如果你,只有明确的调用 无法有效地测试您的程序。