问题
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