Is there a way with Mockito to run a stubbed method of an spied object from an inner class?

爱⌒轻易说出口 提交于 2019-12-10 11:18:01

问题


I'm writing junit tests using Mockito for a code that has been implemented by someone else. Simplifying:

  • There is an Outer class and an Inner class
  • The Outer class keeps an instance of the Inner class.
  • The Inner class uses a method of the Outer class.

The simplified code could looks like this:

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

I want to stub the method getOuterName() of the Outer class to return a value convenient for my test. To do that I'm "spying" on the object:

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

Now, if I call:

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

The stubbed method is invoked in both calls, and I get the string: "outerspied" and "name=outerspied"

However if I call:

spyOuter.getInner().getInnerName(); 

In this case the stubbed method is not called, but the original one. I expected "outerspied-inner", but got "outer-inner"

Summarising, in the spied outer object the reference "this" points to the spied instance. But for the inner object, the reference to "Outer.this" points to a "non spied" instance.

I don't know if I'm doing something wrong, it is a bug, or it is working as designed; question is: is there a workaround?

Many thanks in advance


回答1:


I spy only surrounds the spied object with a proxy. It does not have any mechanism to replace calls within the spied object. So even if a method is stubbed via the spy, if the spied object calls that method directly the spied object's method is invoked not the spy's stub. This is basically exactly what is going on with your Inner / Outter. If Inner were not using the this instance of Outter you might be able to use reflection to replace Inner's reference to Outter. But since Inner is an instance inner class (instead of static) and since invocation of getOutterName is using the implicit Outter.this you don't have a mechanism to override this.



来源:https://stackoverflow.com/questions/22638583/is-there-a-way-with-mockito-to-run-a-stubbed-method-of-an-spied-object-from-an-i

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!