Mockito有没有办法从内部类中运行一个间谍对象的存根方法?

时间:2014-03-25 15:08:27

标签: java junit mockito inner-classes

我正在使用Mockito为其他人实施的代码编写junit测试。 简化:

  • 有一个外类和一个内部类
  • Outer类保留Inner类的实例。
  • Inner类使用Outer类的方法。

简化代码可能如下所示:

public class Outer {
    private Inner inner;

    public Outer(){
         inner=new Inner();
    }

    public Inner getInner(){
        return inner;
    }

    public String getOuterName(){
        return "outer";
    }

    public String getOuterNiceName(){
        return "name="+getOuterName();
    }

    public class Inner {
        public String getInnerName(){
            return getOuterName()+"-inner";     
        }
    }
}

我想将Outer类的方法getOuterName()存根,以返回一个方便我测试的值。 要做到这一点,我就是"间谍"在对象上:

Outer outer=new Outer();
Outer spyOuter=spy(outer);
doReturn("outerspied").when(spyOuter).getOuterName();

现在,如果我打电话:

spyOuter.getObjectName(); 
spyOuter.getOuterNiceName(); 

在两个调用中都调用了stubbed方法,我得到了字符串:" outerspied"  和" name = outerspied"

但是,如果我打电话:

spyOuter.getInner().getInnerName(); 

在这种情况下,不会调用存根方法,而是调用原始方法。我期待" outerspied-inner",但得到"外在"

总结,在间谍外部对象中引用" this"指向间谍实例。 但是对于内部对象,引用了" Outer.this"指向"非间谍"实例

我不知道我做错了什么,这是一个错误,还是按照设计工作;问题是:有解决方法吗?

非常感谢提前

1 个答案:

答案 0 :(得分:2)

spy仅使用代理围绕间谍对象。它没有任何机制来替换spied对象中的调用。因此,即使方法是通过间谍存根的,如果间谍对象直接调用该方法,则调用间谍对象的方法而不是间谍的存根。这基本上与您的Inner / Outter完全相同。如果Inner未使用this Outter实例,您可以使用反射替换Inner'sOutter的引用。但由于Inner是一个实例内部类(而不是静态),并且由于getOutterName的调用使用了隐式Outter.this,因此您没有机制来覆盖它。