简体   繁体   中英

How does a Mockito spy know when it is spying?

This code from the documentation is totally baffling me:

List list = new LinkedList();
List spy = spy(list);

when(spy.size()).thenReturn(100); // <--- how does this spy know 
// not to call the real method????

//using the spy calls *real* methods
spy.add("one");
spy.add("two");

I get it, Mockito is weird and hardly still in Java. Confusing thing is spy.* has to evaluate fully before it knows whether it's wrapped in a when() or something. How on earth would the first spy.* method not call on the real object but the later ones doe?

According to the documentation the first when(spy.size()).thenReturn(100) will actually invoke the real List.size() method, see: http://mockito.github.io/mockito/docs/current/org/mockito/Mockito.html#13

Each subsequent call of course will then return the mocked result.

If you don't want the real method to be called (eg when(spy.get(0)).thenReturn(...) would probably throw an IndexOutOfBoundsException , you have to use this pattern: doReturn(...).when(spy).get(0);

I don't know the exact implementation, but I can take a guess.

The call to spy(...) first proxies the given object and keeps it as a reference to delegate calls.

The call

when(spy.size()).thenReturn(100);

is practically equivalent to

Integer result = spy.size();
OngoingStubbing<Integer> stubbing = when(result); // result is useless
stubbing.thenReturn(100);

The first call to size() is invoked on the proxy. Internally, it can register the call, pushing it, for example, on a static (global) Mockito stack. When you then invoke when() , Mockito pops from the stack, recognizes the call to size() as needing stubbing and performs whatever logic required to do so.

This can explain why stubbing in a multithreaded environment is bad business.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM