部分mock
在測試過程中,有個類的部分方法可能需要實際調用只祠,而某些方法則是被mock的兜蠕,也就是部分mock的場景。在Mockito中抛寝,可以使用Spy來實現(xiàn)熊杨。首先來看一個最簡單的案例
public class SpyDemo {
@Spy
List<String> spy= new ArrayList<String>(); ;
@BeforeEach
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void TestSimpleSpy() {
spy.add("one");
spy.add("two");
when(spy.size()).thenReturn(100);
assertThat(spy.size()).isEqualTo(100);
assertThat(spy.get(0)).isEqualTo("one");
}
對于Spy來說曙旭,沒有被打樁的調用默認都會執(zhí)行真實的方法,如果是打過樁的則返回樁實現(xiàn)晶府。在上述案例中桂躏,spy.size()通過樁實現(xiàn)返回了值100,而spy.get(0)則返回了實際值川陆。
When(obj.do()) 還是 when(obj).do() ?
@Test
public void TestSayHello() {
Demo demo=spy(new Demo();
when(demo.hello()).thenReturn("Ni hao r u");
assertThat(demo.hello()).isEqualTo("Ni hao r u");
}
class Demo {
public String hello() {
System.out.println("hello");
return "hello";
}
}
通過執(zhí)行這個用例剂习,會發(fā)現(xiàn)雖然用例執(zhí)行通過了,也就是demo.hello()的調用結果為返回"Ni hao r u"较沪。但是鳞绕,Mockito除了按照測試樁返回預期值之外,還調用了真實的hello()方法尸曼,也就是在終端打印出了“hello”们何。
換一種寫法,使用doReturn.when的方式骡苞,
@Test
public void TestSayHello2() {
doReturn("Ni hao r u").when(demo).hello();
assertThat(demo.hello()).isEqualTo("Ni hao r u");
reset(demo);
assertThat(demo.hello()).isEqualTo("hello");
}
在這個情況下,真實的hello方法就不會被調用了垂蜗。
When(obj.do()) 還是 when(obj).do()的寫法楷扬,在介紹之前void方法測試時其實也有涉及到解幽。由于when(obj.do())的類型檢查,void方法采用這種寫法烘苹,會直接在編譯器的語法檢查中失敗躲株。
Mockito.reset
在測試過程中,如果在設置了測試樁之后镣衡,還想調用真實方法來執(zhí)行霜定,則可以使用Mockito.reset來重置spy。如上一個用例中廊鸥,在第二次調用demo.hello()方法前調用了reset方法重置demo,因此望浩,這次方法調用的返回值就是”hello”。
總結一下惰说,
1)When(obj.do()).thenXXX方法是類型安全的
2)doXX().when(obj).do()方法可以避免在spy時默認執(zhí)行真實方法
3)可以通過reset方式去掉測試樁