簡體   English   中英

Mockito 模擬超類調用

[英]Mockito mocking super class calls

基類

class BaseSplitter{
    public int splitSalaryHalf(String personName,int Salary){
        //check if person is employee
        //check is person eligible
        //some more check if yes
        //split salary into salary/2 else return -1
        return salary/2 or -1
    }
    public int abc(){
    }
}

派生類

class Bonus extends BaseSplitter{
    public int giveBonous(String personName,int salary){
        int bonusamount = super.splitsalaryHalf("Sunil",super.splitSalary("Sunil",salary));
        if(bonusamount == -1){
            return 0;
        }
        return Salary + bonusamount
    }
}

我正在嘗試使用 mockito測試 giveBonus函數但失敗

public class Bonus {

    @Test
    public void giveBonous() throws Exception{
        GiveBonus bonus = Mockito.spy(new Bonus);
        doReturn(500).when((BaseSplitter)Bonus).splitSalaryHalf("sunil",2000);
        int num = bonus.giveBonus("sunil",2000);
        assertEqual(2500,num);
    }
}

問題#1

問題是 mockito 不是在splitHalfSalary超類( splitHalfSalary )調用,而是開始實際調用它( splitSalaryHalf函數,它包含一些復雜的對象{不包括以保持簡單})。 我如何模擬超類方法。

問題2

不應用組合,因為我需要派生類中的abc()和其他函數。 如果是,我是否應用了錯誤的模式? 我應該如何處理?

診斷這一點變得更加困難,因為您上面粘貼的代碼不是真正的代碼。 例如,測試需要“sunil”,但實際代碼使用“Sunil”。 這說明了復制確切代碼並粘貼到您的問題中的重要性。

我認為實際的答案與super關鍵字的使用有關。 如果您從代碼示例中刪除 super 關鍵字,它將按預期工作。

Mockito 正在創建類似於原始對象的動態代理的東西,並在您創建間諜時包裝它。 真實對象仍然存在,對 giveBonous() 的調用由間諜代理委托給真實對象。

真實對象調用 super.splitSalaryHalf ,Java 中說,不要調用此對象對 splitSalaryHalf 的覆蓋——直接轉到超類對此方法的定義並調用它。

間諜使您能夠模擬包裝對象 (Bonus.splitSalaryHalf) 上的方法,但不會替換超類實現。

Mockito 的行為是完全合適的,因為一個常見的模式是覆蓋子類中的超類實現,但仍然能夠調用超類的實現。 考慮一下:

public class BonusCalculator {
  private double bonusFactor = 0.10;

  public int giveBonus(Employee employee) {
    return employee.getSalary() * bonusFactor;
  }
}

public class AuditableBonusCalculator extends BonusCalculator {
  public int giveBonus(String name, int salary) {
    int bonus = super.giveBonus(name, salary);
    updatePayrollAudit(employee, bonus);
    return bonus;
  }
}

超類 BonusCalculator 計算實際的獎金金額。

子類 AuditableBonusCalculator 委托超類獲取實際獎金金額,但增加了更新工資審計系統以顯示獎金已支付的責任。

Mockito 只用代理包裝子類,並且只能攔截對該特定類的調用。 只要調用是通過代理調度的,您仍然可以模擬由超類實現的方法,如果super關鍵字不存在,它就會這樣做。 但是如果你使用 super 關鍵字,Java 不會顯式地考慮當前對象的實現,它會去尋找超類的那個方法的實現並顯式調用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM