SpringBoot整合Mockito、PowerMockito單元測試

一、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

https://www.cnblogs.com/nizuimeiabc1/p/12173907.html

https://www.cnblogs.com/nizuimeiabc1/p/12173883.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容