使用 Mockito WhiteBox 在方法范围内设置成员变量

Using Mockito WhiteBox for setting a member variable inside a method scope

我是 Mockito 的新手,正在尝试弄清楚是否有一种方法可以使用 Mockito 的 WhiteBox 功能在 public 方法中设置成员变量的值。

我试着搜索这个,但似乎没有参考资料在谈论这个。

是否可行

谢谢

添加了我想要实现的示例。考虑以下 class.

public class FinancialsCalculator {
    private int va11;
    private int val2; 

    public int calculateFinancialsAppliedSum() {
        //In actual application this calc get's Injected using Guice
        Calculator calc;

        //Some pre-processing to the values val1 and val2 will be performed here

        return calc.getSum(val1, val2);
    }
}

现在我需要对上面的内容进行单元测试class。我想在 calculateFinancialsAppliedSum 方法的范围内模拟 Calculator class 实例。

如果它在 FinancialsCalculator class 级别(即与 val1 和 val2 变量处于同一级别),我可以轻松地模拟它并使用 mockito 的 Whitebox.setInternalState() 来设置模拟实例到 class 级别的计算器私有实例。

不幸的是,由于其他原因,我无法将此计算器实例设为 FinancialsCalculator class 的 class 级私有实例。它必须在 calculateFinancialsAppliedSum 方法中。

那么如何在 calculateFinancialsAppliedSum 方法中模拟这个 Calculator 实例以进行测试?

没有办法像你描述的那样做; WhiteBox 和类似工具可以更改实例字段的值,因为它是持久的,但方法变量仅在方法执行时才存在于堆栈中,因此无法从方法外部访问或重置它。

因为计算器是通过 Guice 注入的,所以可能有一个很好的注入点(方法、字段或构造函数),您可以在测试中调用自己来插入计算器模拟。

您还可以重构以使测试更容易:

public class FinancialsCalculator {
    private int va11;
    private int val2; 

    public int calculateFinancialsAppliedSum() {
        return calculateFinancialsAppliedSum(calc);
    }

    /** Uses the passed Calculator. Call only from tests. */
    @VisibleForTesting int calculateFinancialsAppliedSum(Calculator calc) {
        //Some pre-processing to the values val1 and val2 will be performed here
        return calc.getSum(val1, val2);
    }
}

或者甚至将方法设为静态,以便可以使用完全任意的值对其进行测试:

public class FinancialsCalculator {
    private int va11;
    private int val2; 

    public int calculateFinancialsAppliedSum() {
        return calculateFinancialsAppliedSum(calc, val1, val2);
    }

    /** Uses the passed Calculator, val1, and val2. Call only from tests. */
    @VisibleForTesting static int calculateFinancialsAppliedSum(
            Calculator calc, int val1, int val2) {
        //Some pre-processing to the values val1 and val2 will be performed here
        return calc.getSum(val1, val2);
    }
}