This is the magic of proxies.
The javadoc of [Mockito.spy()][1]
states
Creates a spy of the real object. The spy calls real methods unless they are stubbed.
So spy()
returns a mock object, which is a proxy. It is a sub class of Foo
so it inherits the methods, but it wraps their execution in a interceptor method. This method has a try catch block which catches any exception thrown in the actual method invocation. The catch block then uses a ConditionalStackTraceFilter
to clean up the stack trace. To do this, it uses a StackTraceFilter
which in the comments of its filter(..)
method states
/**
* Example how the filter works (+/- means good/bad):
* [a+, b+, c-, d+, e+, f-, g+] -> [a+, b+, g+]
* Basically removes all bad from the middle. If any good are in the middle of bad those are also removed.
*/
The call stack at the invocation of baz()
is something like (super simplified)
at Foo.baz()
at FooPROXY.baz()
at Foo.bar()
at FooPROXY.bar()
at Foo.foo()
at FooPROXY.foo()
at MockTest.test()
All the PROXY
stack trace elements, which are the proxies and the interceptors involved, and everything in between get removed. So you get the result you see.
Note that Junit also cleans it up so as not to show its internals.