我正在尝试理解以下场景的测试,在该场景中,应该模拟第一次创建地图,而不应模拟第二实例的创建,并且我按照以下方式编写,它在一个场景中有效,而在以后的场景中不起作用,
public class A {
public void test(){
Map<String,String> map = new HashMap<String, String>();
Map<String,String> map1 = new HashMap<String, String>();
System.out.println(map);
System.out.println(map1);
}
}
编写测试的第一种方式可以正常工作
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class ATest {
@Test
public void test() throws Exception{
HashMap<String,String> map = PowerMockito.mock(HashMap.class);
HashMap<String,String> hashMap = new HashMap<String, String>();
PowerMockito.whenNew(HashMap.class).withNoArguments().thenReturn(map,hashMap);
A a = new A();
a.test();
}
}
我直接传递新的HashMap()的第二种方式,这会引发异常,
@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class ATest {
@Test
public void test() throws Exception{
HashMap<String,String> map = PowerMockito.mock(HashMap.class);
PowerMockito.whenNew(HashMap.class).withNoArguments().thenReturn(map,new HashMap<String,String>());
A a = new A();
a.test();
}
}
任何人都可以让我知道为什么当我直接通过HashMap时.....不起作用吗?
答案 0 :(得分:0)
在第二项测试中,您违反了Mockito验证系统施加的顺序约束。 Mockito验证您是否正确使用其方法,如果不正确,则抛出UnfinishedStubbingException
。
PowerMockito.whenNew(HashMap.class).withNoArguments().thenReturn(map,new HashMap<String,String>());
首先,执行对whenNew()
的调用。这会导致Mockito拦截对HashMap::new
的所有后续调用。但是,您实际上还没有告诉它要返回什么(thenReturn()
部分尚未运行),因此调用HashMap
构造函数现在无效。如果这样做,将会遇到异常。
现在让我们看一下thenReturn()
部分。完成后,您可以再次安全地调用HashMap::new
– Mockito将知道返回什么。但是在调用thenReturn()
之前,必须先解决其所有参数。这导致HashMap
构造函数被过早调用-因此是异常。调用它时,对于HashMap::new
,您已使Mockito处于无效的中间状态。因此它引发了异常。
相反,您的第一个测试很好,因为您是在告知Mockito拦截呼叫之前实例化HashMap
。