我有以下课程(虚构,仅用于演示问题):
public class MySingleton {
private static MySingleton sMySingleton;
private static List<String> sItemList;
private MySingleton(List<String> list) {
sItemList = list;
}
public static MySingleton getInstance(List<String> list) {
if (sMySingleton == null) {
sMySingleton = new MySingleton(list);
}
return sMySingleton;
}
public void addItem(String item) {
sItemList.add(item);
}
public void removeItem(String item) {
sItemList.remove(item);
}
}
一个相应的测试类:
public class MySingletonTest {
private MySingleton mInstance;
private List<String> mList;
@Before
public void setup() {
mList = mock(List.class);
mInstance = MySingleton.getInstance(mList);
}
@Test
public void testAddItem() throws Exception {
String item = "Add";
mInstance.addItem(item);
verify(mList, times(1)).add(item);
}
@Test
public void testRemoveItem() throws Exception {
String item = "Remove";
mInstance.removeItem(item);
verify(mList, times(1)).remove(item);
}
}
如果我现在执行完整的测试类,Mockito告诉我测试testRemoveItem()
与模拟有0次交互。
这怎么可能?
注意:
请不要开始讨论感觉单身人士。
这个问题是关于Mockito以及为什么它不起作用。
答案 0 :(得分:1)
JUnit为每个测试创建一个新的测试类实例,Mockito为每个测试填充一个新的模拟实例。但是,您的单身人士只会初始化一次,这意味着在第一次测试期间mList == MySingleton.sItemList
,但在此之后每次测试都会mList != MySingleton.sItemList
。
换句话说,互动正在发生,但是通过第二次测试,你会检查错误的模拟。
虽然我知道你并不是在这里讨论这种单身人士的优点,但请记住,如果你这样做,你可能很难在测试中替换实例。相反,请考虑使单例的构造函数(仅)可用于您的测试,并在实例中保持List
(或其他状态)。这样你就可以创造一个全新的&#34; Singleton&#34;对于每个单独的测试。