简体   繁体   English

Mockito 模拟超类调用

[英]Mockito mocking super class calls

Base class基类

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(){
    }
}

Derived class派生类

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
    }
}

I am trying to test giveBonus function with mockito but failing我正在尝试使用 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);
    }
}

Question # 1问题#1

The issue is that mockito is not mocking the superclass( splitHalfSalary ) call rather start calling it in real ( splitSalaryHalf function which contains some complex object{not included to keep it simple} ).问题是 mockito 不是在splitHalfSalary超类( splitHalfSalary )调用,而是开始实际调用它( splitSalaryHalf函数,它包含一些复杂的对象{不包括以保持简单})。 How can i mock superclass method.我如何模拟超类方法。

Question # 2问题2

Not applying a composition as I need abc() and other functions in the derived class.不应用组合,因为我需要派生类中的abc()和其他函数。 Am I applying wrong pattern if Yes?如果是,我是否应用了错误的模式? how should I handle the same?我应该如何处理?

Diagnosing this is made harder because the code you pasted above isn't the real code.诊断这一点变得更加困难,因为您上面粘贴的代码不是真正的代码。 For example, the test expects "sunil" but the actual code uses "Sunil".例如,测试需要“sunil”,但实际代码使用“Sunil”。 This illustrates the importance of copying the exact code and pasting into your question.这说明了复制确切代码并粘贴到您的问题中的重要性。

I think the actual answer has to do with the use of the super keyword.我认为实际的答案与super关键字的使用有关。 If you remove the super keyword from the code example it will work as intended.如果您从代码示例中删除 super 关键字,它将按预期工作。

Mockito is creating something similar to a dynamic proxy of the original object and wrapping it when you create a spy. Mockito 正在创建类似于原始对象的动态代理的东西,并在您创建间谍时包装它。 The real object is still there and the call to giveBonous() is delegated to the real object by the spy proxy.真实对象仍然存在,对 giveBonous() 的调用由间谍代理委托给真实对象。

The real object makes a call to super.splitSalaryHalf which in Java says, do not call this object's override of splitSalaryHalf -- go directly to the super class's definition of this method and invoke that.真实对象调用 super.splitSalaryHalf ,Java 中说,不要调用此对象对 splitSalaryHalf 的覆盖——直接转到超类对此方法的定义并调用它。

The spy gives you the ability to mock out methods on the wrapped object (Bonus.splitSalaryHalf) but will not replace the super classes implementation.间谍使您能够模拟包装对象 (Bonus.splitSalaryHalf) 上的方法,但不会替换超类实现。

Mockito's behavior is entirely appropriate because a common pattern would be to override the super class implementation in the subclass, but still have the ability to call the super class's implementation. Mockito 的行为是完全合适的,因为一个常见的模式是覆盖子类中的超类实现,但仍然能够调用超类的实现。 Consider this:考虑一下:

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;
  }
}

The superclass, BonusCalculator, calculates the actual bonus amount.超类 BonusCalculator 计算实际的奖金金额。

The subclass, AuditableBonusCalculator, delegates to the superclass to get the actual bonus amount, but adds the responsibility of updating the payroll audit system to show that the bonus was paid.子类 AuditableBonusCalculator 委托超类获取实际奖金金额,但增加了更新工资审计系统以显示奖金已支付的责任。

Mockito only wraps the subclass with a proxy and can only intercept calls on that specific class. Mockito 只用代理包装子类,并且只能拦截对该特定类的调用。 You can still mock methods implemented by the superclass as long as the call is dispatched through the proxy, which it will if the super keyword is not present.只要调用是通过代理调度的,您仍然可以模拟由超类实现的方法,如果super关键字不存在,它就会这样做。 But if you use the super keyword, Java explicitly does not consider the current object's implementation, it will go find the superclass's implementation of that method and call it explicitly.但是如果你使用 super 关键字,Java 不会显式地考虑当前对象的实现,它会去寻找超类的那个方法的实现并显式调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM