在service層,使用mock來測試代碼。而不再使用Juint測試
JUint是java單元測試的框架,已經在Eclipse中默認的安裝。目前主流的有JUnit3和JUnit4.JUint3中,測試用例需要繼承TestCase類,JUint4中,測試用例無需繼承TestCase類,只需要使用@Test等註解。
JUint4主要通過註解的方式來識別測試方法。目前支持的主要註解有:
@BeforeClass全局只會執行一次,而且是第一個運行。
@Before在測試方法運行之前運行
@Test測試方法
@After在測試方法運行之後允許
@AfterClass全局只會執行一次,而且是最後一個運行
@Ignore忽略此方法
Juint3和JUint4都提供了一個Assert類。Assert類中定義了很多靜態方法來進行斷言。
Mockito與JUint不同,並不是單元測試框架。它是用於生成模擬對象或者直接點說,就是“假對象”的工具。
Mock/Stub
Mock和Stub是兩種測試代碼功能的方法。Mock側重於對功能的模擬,Stub測重於對功能的測試重現,例如對List接口。Mock會直接對List進行模擬,而Stub會新建一個實現了List的TestList,在其中編寫測試的代碼。
強烈建議優先選擇Mock方式,因爲Mock方式下,模擬代碼與測試代碼放在一起,易讀性好,而且擴展性、靈活性都比Stub好。
比較流行的Mock
JMock
EasyMock
Mockito
powermock
其中EasyMcock和Mocking對於Java接口使用接口代理的方式來模擬。對於Java類使用繼承的方式來模擬(即會創建一個新的Class類)。Mockito支持spy方式。可以對實例進行模擬。但他們都不能對靜態方法和final類進行模擬。
Mockito是一個開源項目。Api相對於EasyMock更友好,與EasyMock不同的是,Mockito沒有錄製過程,只需要在“運行測試代碼”之前對接口進行Stub,即設置方法的返回值或拋出的異常。然後直接運行測試代碼。運行期間調用Mock的方法,會返回預先設置的返回值或拋出異常。最後再對測試代碼進行驗證。
- mport static org.mockito.Mockito.*;
- //創建Mock
- List mockedList = mock(List.class);
- //使用Mock對象
- mockedList.add("one");
- mockedList.clear();
- //驗證行爲
- verify(mockedList).add("one");
- verify(mockedList).clear();
首先是配置 Mock 對象,、
-
List mock = mock( List.class );
-
when( mock.get(0) ).thenReturn( 1 );
-
assertEquals( "預期返回1", 1, mock.get( 0 ) );
Mockito支持 迭代風格 的返回值設定,
- 第一種方式 when(i.next()).thenReturn("Hello").thenReturn("World");
- 第二種方式 when(i.next()).thenReturn("Hello", "World");
上面的例子等價於:
-
when(i.next()).thenReturn("Hello");
-
when(i.next()).thenReturn("World");
第一次調用i.next()將返回”Hello”,第二次的調用會返回”World”。
對 void 方法不返回值,所以不能 when(mock.someMethod()).thenReturn(value) 這樣的語法,可以這樣
-
doNothing().when(i).remove();
-
doThrow(Throwable) 模擬返回異常
-
doThrow(new RuntimeException()).when(i).remove();
迭代風格 doNothing().doThrow(new RuntimeException()).when(i).remove();,這樣,第一次調用remove方法什麼都不做,第二次調用拋出RuntimeException異常。
(1)如何將mock的類自動注入到待測類中?
在測試代碼中,使用@Inject將service層注入,@Mock註釋Mapper。
public class AService {
}
public class AServiceTest extends Test4J{
@Inject(targets= { “ AService” })
@Mock
private AMapper aMapper;
}