在作單元測試的時候,有的時候用到的一些類,咱們構造起來不是那麼容易,好比HttpRequest,或者說某個Service依賴到了某個Dao,想構造service還得先構造dao,這些外部對象構造起來比較麻煩。 因此出現了Mock! 咱們能夠用 Mock 工具來模擬這些外部對象,來完成咱們的單元測試。html
實現Mock技術的優秀開源框架有不少,下面以Mockito爲例,用幾個簡單例子來介紹Mock工具的基本使用:java
1 @Test 2 public void simpleTest(){ 3 4 //建立mock對象,參數能夠是類,也能夠是接口 5 List<String> list = Mockito.mock(List.class); 6 7 //設置方法的預期返回值 (若是list.get(0) 被調用 ,調用以後返回 helloworld) 8 //固然前提是要建立了Mock對象,如這裏就是建立了跟 List相關的 Mock對象 9 //這裏還看不出什麼做用,由於Mock 還看不出來,List很容易就能建立 10 //假如是一個很複雜的對象,構造這樣一個對象頗有難度,使用Mock就很方便了,咱們不用去一步一步填充它的屬性去構造, 11 //只須要Mock 一下,就能夠拿到這個對象,去測試它的方法,(固然,若是方法有參數咱們是須要傳遞的,像get(0)) 12 Mockito.when(list.get(0)).thenReturn("helloworld"); 13 //list.get(0)的調用就會返回 helloworld 14 String result = list.get(0); 15 System.out.println(result); 16 17 //驗證方法調用(是否調用了get(0)) 18 Mockito.verify(list).get(0); 19 20 Assert.assertEquals("helloworld", result); 21 }
1 @Test 2 public void testMockMethod() { 3 Class1Mocked obj=mock(Class1Mocked.class);① 4 5 when(obj.hello("z3")).thenReturn("hello l4");② 6 7 String actual=obj.hello("z3");③ 8 assertEquals("hello l4",actual); 9 10 verify(obj).hello("z3");④ 11 //verify(obj,times(1)).hello("z3"); //能夠加參數驗證次數 12 }
1 @Test 2 public void testMockMethodInOrder() { 3 Class1Mocked objOther = Mockito.mock(Class1Mocked.class); 4 Class1Mocked objCn = Mockito.mock(Class1Mocked.class); 5 6 Mockito.when(objOther.hello("z3")).thenReturn("hello l4"); 7 Mockito.when(objCn.hello("z3")).thenReturn("hello 張三"); 8 9 String other = objOther.hello("z3"); //這裏決定了 objOther在先 10 Assert.assertEquals("hello l4", other); 11 String cn = objCn.hello("z3"); //這裏決定了 objCn在後 12 Assert.assertEquals("hello 張三", cn); 13 14 InOrder inOrder = Mockito.inOrder(objOther, objCn); //此行並不決定順序,下面的兩行纔開始驗證順序 15 inOrder.verify(objOther).hello("z3"); 16 inOrder.verify(objCn).hello("z3"); 17 }
1 // 非局部模擬(只能經過When().thenReturn() 來指定函數的返回類型,可是是調用不了 模擬出來的的類的方法的) 2 @Test 3 public void testSkipExpect() { 4 Class1Mocked obj = Mockito.mock(Class1Mocked.class); 5 6 //如:正常若是hello方法被調用,應該返回z3,但這裏返回的null ,說明該方法是沒有被調用的 7 //由於咱們模擬出來的是非局部變量 8 Assert.assertEquals(null, obj.hello("z3")); 9 //show方法也是同樣,show方法若是執行應該打印一句話,可是obj並不能執行show方法 10 obj.show(); 11 12 Mockito.verify(obj).hello("z3"); 13 Mockito.verify(obj).show(); 14 }
1 //局部模擬--spy()方式 2 @Test 3 public void testSpy() { 4 Class1Mocked obj = Mockito.spy(new Class1Mocked()); 5 6 Mockito.doNothing().when(obj).show(); //有了這行,show方法被執行就不會有任何操做 7 8 Assert.assertEquals("z3",obj.hello("z3")); 9 obj.show(); 10 11 Mockito.verify(obj).hello("z3"); 12 Mockito.verify(obj).show(); 13 }
1 //值得注意的陷阱 2 @Test 3 public void testSpy2() { 4 Class1Mocked obj = Mockito.spy(new Class1Mocked()); 5 //即便使用的是when thenReturn,可是仍然會執行方法裏面的內容 6 Mockito.when(obj.hello("z3")).thenReturn("hello l4"); 7 8 Assert.assertEquals("hello l4",obj.hello("z3")); 9 10 Mockito.verify(obj).hello("z3"); 11 }
1 //若是既想使用局部模擬,又不想調用到方法裏面的內容 2 @Test 3 public void testSpy3() { 4 Class1Mocked obj = Mockito.spy(new Class1Mocked()); 5 6 Mockito.doReturn("hello l4").when(obj).hello("z3"); 7 8 Assert.assertEquals("hello l4",obj.hello("z3")); 9 10 Mockito.verify(obj).hello("z3"); 11 }
參考博文:java的mock測試框架框架