繁体   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