mockito mock void方法_Spock如何模拟抽象类方法
我們平時寫單元測試時經常會遇到調用抽象類或父類的方法,這些抽象方法可能是調用底層接口或數據庫,需要mock掉,讓抽象方法返回一個我們指定的值,以便測試當前代碼邏輯的場景。
下面講下Spock如何結合power mock實現動態mock抽象方法
一. 抽象方法或父類方法動態mock
AbstractService?是個抽象類,我們需要把它的方法?parentMethod?模擬掉,返回我們預先設置的"期望值"?
代碼示例:
public?abstract?class?AbstractService?{String parentMethod(){// 發起接口調用或數據庫操作return?"parentMethod value";
????}
}
SubService是繼承AbstractService?的子類,在doSomething方法體里會調用抽象類的?parentMethod?方法邏輯,然后根據抽象方法?parentMethod?的返回值走不同的邏輯:
public?class?SubService?extends?AbstractService?{
????@Autowired
????MoneyDAO moneyDAO;public?String doSomething() {
????????String parent?= super.parentMethod(); // 調用抽象類或父類方法if?("parent1".equals(parent)) {// 執行parent1分支邏輯return?"sub1";
????????}if?("parent2".equals(parent)) {// 執行parent2分支邏輯return?"sub2";
????????}if?("parent3".equals(parent)) {// 執行parent3分支邏輯return?"sub3";
????????}return?"other";
????}
}
如果要mock掉抽象類AbstractService?中的?parentMethod?方法, 并且每次mock的值不一樣, 可以使用spock + powermock來實現:
單元測試代碼如下:
/**
?* 測試抽象類方法或父類方法
?* @Author: www.javakk.com
?* @Description: 公眾號:Java老K
?* @Date: Created in 14:53 2020/10/05
?* @Modified?By:
?*/@RunWith(PowerMockRunner.class)@PowerMockRunnerDelegate(Sputnik.class)@PrepareForTest([SubService.class])class?AbstractServiceTest?extends?Specification?{@Unroll
????def "測試抽象方法"() {
????????given: "mock抽象類方法"
????????def sub = PowerMockito.mock(SubService)
????????PowerMockito.when(sub.parentMethod()).thenReturn(parentValue) // mock掉抽象類的parentMethod, 返回動態mock值:mockParentReturn
????????PowerMockito.when(sub.doSomething()).thenCallRealMethod()
????????expect: "調用doSomething方法"
????????sub.doSomething() == result
????????where: "驗證分支場景"
????????parentValue | result"parent1"???| "sub1""parent2"???| "sub2""parent3"???| "sub3""parent4"???| "other"
????}
}
使用power mock模擬掉抽象類的方法,返回一個變量parentValue,然后再放在Spock的where標簽里,即可實現動態mock的效果,即每次調用返回的mock值都不一樣:parent1、parent2、parent3 ...
二. 抽象方法+實例方法的動態mock
如果在SubService中還有引用其他實例對象的方法,比如下面的業務代碼:
public?class?SubService?extends?AbstractService?{
????@Autowired
????MoneyDAO moneyDAO; // 金額換算對象public?String doSomethingAndDao() {
????????String parent?= super.parentMethod(); // 調用抽象類或父類方法
????????BigDecimal money = moneyDAO.getExchangeByCountry(parent); // 獲取對應國家的金額if?("parent1".equals(parent)) {return?money + " CNY";
????????}if?("parent2".equals(parent)) {return?money + " USD";
????????}if?("parent3".equals(parent)) {return?money + " EUR";
????????}return?money.toString();
????}
}
如果即要mock掉抽象類AbstractService?中的?parentMethod?方法,又要mockmoneyDAO對象,可以使用 Whitebox.setInternalState 方式
單元測試代碼如下:
/**
?* 測試抽象類方法或父類方法
?* @Author: www.javakk.com
?* @Description: 公眾號:Java老K
?* @Date: Created in 14:53 2020/10/05
?* @Modified?By:
?*/@RunWith(PowerMockRunner.class)@PowerMockRunnerDelegate(Sputnik.class)@PrepareForTest([SubService.class])class?AbstractServiceTest?extends?Specification?{@Unroll
????def "測試抽象方法和實例方法"() {
????????given: "mock抽象類方法"
????????def sub = PowerMockito.mock(SubService)// mock掉抽象類的parentMethod, 返回動態mock值:mockParentReturn
????????PowerMockito.when(sub.parentMethod()).thenReturn(parentValue)
????????PowerMockito.when(sub.doSomethingAndDao()).thenCallRealMethod()
????????def moneyDAO = Mock(MoneyDAO)//將Spockmock的對象moneyDAO使用powermock賦值給SubService的引用moneyDAO
????????Whitebox.setInternalState(sub, "moneyDAO", moneyDAO)
????????moneyDAO.getExchangeByCountry(_) >> money // 這樣就可以使用spock的動態mock
????????expect: "調用doSomething方法"
????????sub.doSomethingAndDao() == result
????????where: "驗證分支場景"
????????parentValue | money || result"parent1"???| 100???|| "100 CNY""parent2"???| 200???|| "200 USD""parent3"???| 300???|| "300 EUR""parent4"???| 400???|| "400"
????}
}
關于動態mock的更多用法可以參考這篇文章:Spock高級用法 - 動態mock
(完整的代碼已上傳到github,在公眾號里回復spock即可獲取github項目地址)
-END-推薦閱讀:Spock高級用法 - 動態mockSpock代碼講解 - 靜態方法測試Spock代碼講解 - void方法測試Spock代碼講解 - 異常測試Spock代碼講解 - if esle 分支場景測試互聯網一線java開發老兵,工作10年有余,夢想敲一輩子代碼,以夢為碼,不負韶華。
掃碼關注Java老K,獲取更多Java干貨。
總結
以上是生活随笔為你收集整理的mockito mock void方法_Spock如何模拟抽象类方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一亿像素!POCO X5 Pro实拍图曝
- 下一篇: 正则匹配问号_爬虫之正则表达式