一、Mockito 概念圖

image.png
二、 前要知識
1、測試的類型
- Unit test : 單元測試是關注單一的類,檢查這個類中的代碼是否按預期正確執(zhí)行
- Integration test:檢查開發(fā)的模塊和其它模塊整合時是否正確執(zhí)行
- End-to-End test:將整個系統(tǒng)作為一個整體,然后從用戶的角度去進行測試,看系統(tǒng)在實際應用中是否正確執(zhí)行
2、單元測試概念
- 被測系統(tǒng)(System under test,SUT):被測系統(tǒng)是當前被測試的系統(tǒng),目的是檢查當前被測的系統(tǒng)是否被正確運行,根據測試系統(tǒng)的不同,SUT 所指代的內容也不同,可以是一個類也可以是整個系統(tǒng)。
- 測試依賴組件(DOC):被測系統(tǒng)所依賴的組件,例如:進行 UserService 的單元測試時,UserService 會依賴 UserDao ,那么 UserDao 就是 DOC
- 測試替身(Test Double):用一些功能簡單的且其行為和實際對象類似的假對象來作為 SUT 的依賴對象
- Test stub:為 SUT 提供假數據的對象
- Fake object:實現了簡單功能的一個假對象
- Mock object:用來模擬實際的對象,并校驗當前的 mock object 的方法是否符合預期
- Dummy object:在測試中并不使用,但是為了測試代碼正常的編譯/運行而添加的對象(比如僅僅填充參數列表)
- Test spy:包裝一個真實的 Java 對象,并返回一個包裝后的新對象,對這個新對象的所有方法進行調用時,都會委派為實際的對象。
三、Mockito、PowerMockito
首先引入maven依賴
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.0</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
指定執(zhí)行方式
@RunWith(PowerMockRunner.class)
指定需要被mock的靜態(tài)類
@PrepareForTest({ LoginUtil.class })
mock方法
//mock靜態(tài)類
PowerMockito.mockStatic(LoginUtil.class);
//mock帶返回值的方法
PowerMockito.when(LoginUtil.getUser()).thenReturn(new LoginUser());
//mock沒有返回值(void)的方法
doNothing().when(bookService).deleteBookById(Mockito.any(),Mockito.any());
//mock調用方法拋出異常
doThrow(new RuntimeException()).when(bookService).addBook(Mockito.any(),Mockito.any());
在測試類中,只要將待測的類標注為@InjectMocks,將其依賴的其他類標注為 @Mock,就可以使用MockitoAnnotations.initMocks(this);這句話自動將依賴的類注入待測類,如果依賴類在spring的管理下有自己的name,那么甚至在待測類中都不需要寫setter方法。
@InjectMocks
BookServiceImpl bookService;
@Mock
BookDaoImpl bookDao;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
//這句話執(zhí)行以后,bookDao等bookService依賴的bean會自動注入到abcService中。
}
完整的測試類,上面說的不明白的可以參考下面的代碼:
1、待測類
@Service
public class AbcService {
@Autowired
private AaaDao aaaDao;
@Autowired
private BbbDao bbbDao;
......//注:此處省略的代碼中并不包含aaaDao和bbbDao的setter方法。
}
2、測試類
//使用這個跑單測,所有目標類調用的服務都需要mock,不會加載容器支持靜態(tài)方法mock
@RunWith(PowerMockRunner.class)
//如果有調用其他類中的靜態(tài)方法,則需要指定被mock的靜態(tài)資源類,沒有的話則不需要
//@PrepareForTest({ LoginUtil.class })
public class AbcServiceTest{
@InjectMocks
AbcService abcService;
@Mock
AaaDao aaaDao;
@Mock
BbbDao bbbDao;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);//這句話執(zhí)行以后,aaaDao和bbbDao自動注入到abcService中。
//在這之后,你就可以放心大膽地使用when().then()、
//Mockito.doNothing().when(obj).someMethod()、
//doThrow(new RuntimeException()).when(obj).someMethod(Mockito.any());
//等進行更詳細的設置。
}
@Test
public void addAbc() {
when(aaaDao.addAbc()).thenReturn(ABCDO);
when(bbbDao.addAbc(Mockito.any(),Mockito.any())).thenReturn(1);
PojoResult pojoResult = abcService.addAbc(AbcVo);
//最后這里加上斷言,進行判斷執(zhí)行結果是否達到我們的預期
TestCase.assertEquals(true,pojoResult.getContent());
}
}
拓展閱讀:
power mock 入門介紹及使用示例
PowerMockito使用詳解
使用PowerMock模擬私有字段和私有方法
PowerMock應用二:模擬new對象
https://www.cnblogs.com/nizuimeiabc1/p/12173948.html