1

Extending - https://stackoverflow.com/a/29394497/1260692 (as stackoverflow doesn't allow me to comment without 50 reputation)

Why does a real method is called on spies during mock setup in when/then style?

I see that org.powermock.api.mockito.internal.expectation.DefaultMethodExpectationSetup (Mockito version 1.5.6) calls the actual method in line numbers - 44, 46 and 52. Can some Mockito expert explain why is this happening and how to avoid this?

FYI, when I switch to doReturn/when style, no issues. Test runs as expected.

Community
  • 1
  • 1
Sathish Kumar
  • 87
  • 1
  • 6
  • *why is this happening* Why wouldn't it? *how to avoid this* Don't use when/thenReturn, but doReturn/when instead. – Manu Dec 08 '15 at 10:00
  • That's really useless. Give some informative answer or stay away. My aim is to learn how a stub imitates actual implementation and why ongoing stubbing fails while the other doesn't. If you have anything to share in detail about doReturn/when implementation, please do. – Sathish Kumar Dec 08 '15 at 12:48
  • The question is really useless. Asking **why** when/thenReturn does one thing and doReturn/when does another is like asking why `a+1` increments a and `a-1` decrements it. That's just how it is. If you actually want to ask something else, then ask what you mean. – Manu Dec 08 '15 at 13:14
  • These are two different ways of stubbing, totally agreed. But both are meant for creating stubs. All I want to know is, why the **call goes to the real method** instead of a Mockito stub **when I set an expectation** using when/then construct? – Sathish Kumar Dec 08 '15 at 13:31
  • Please read my previous comment again... – Manu Dec 08 '15 at 13:50

1 Answers1

0

Without knowing the ins and outs of PowerMock, but calling when(foo.method())... is executed using the usual Java semantics: first the method call foo.method(), then the rest using the result of the call. Now, foo is a mocked object at that time, created by PowerMock. It is not empty but has a whole bunch of logic that records calls. This mock object records the call to method(). Then the when() method call is executed and queries the mock object that is currently being stubbed about which method was called last and with which parameters. This information is used to configure the stubbed return value.

Mockito's API looks like magic, but it is just a very cleverly designed API with a ton of totally normal Java code to get it working. :-)

Edit:

Explained in other words: in when(foo.method()), foo is a mock object that has a method method() whose code has nothing to do with that of the original object, but deals with recording calls to the method. So, since this is, after all, plain Java, first foo.method() is executed. It returns some arbitrary value according to the interface of the original method signature (e.g. an int when method() would usually return an int). To get the information to Mockito, that you're about to stub foo.method(), the mock objects communicates to Mockito "dude, I just got called". Methods with parameters also communicate the parameters they were called with to Mockito. So, Mockito's when() memorize that call and returns an object with a thenReturn() method. Before this is called, its parameter is evaluated. The value is then passed to the thenReturn() method, which communicates to Mockio "dude, when asked, return this". Mockito knows it's in the process of stubbing a call to foo.method() and connects the return value internally to the call. So later, when the mock is called using the foo.method(), it looks up the return value and returns it.

I kind of doubt that the other way of expressing this (doReturn().when()) works fundamentally differently.

xmjx
  • 1,163
  • 1
  • 7
  • 18
  • I think I got what you explained but only partially. Summarizing - "Every time, call to real method is made. For mock objects, unset expectations is equivalent to empty implementation while for spies, they are real implementations. And that's why I see such behavior" Just one more question - why real methods are not called during doReturn/when style of expectation setup? – Sathish Kumar Dec 08 '15 at 12:24