Since you basically asked me to rewrite my comment modified by your answer as an answer, here it is:
Try using reflection as in:
when(method.invoke(mock)).thenReturn("Hello world.");
although, I'm not sure how this works for you, since you cannot mock the Method
class (it's final). Mockito when()
only works on taunts or spies. If this really works for you, can you post a little more details?
If this does not work, you can - as I suggested in my comment on OP - go along the CGLib route and bypass Mockito. It really is not as difficult as it seems at first glance. In my OSS Funcito project (not a mocking structure), I removed a lot of Mockito CGLib proxy code and rewrote it for my needs. This gives a much simpler look at the world of proxy classes and intercepts method calls.
AN EXTRA RESPONSE TO COMMENTS I see how this works for you, but I'm not sure that you really understand how it works. The reason this may matter is because future changes to Mockito itself may lead to a breach of your decision in the future. In fact, the reason it works is almost random, but yes, it will work.
The way that when()
should work is that what happens between the parentheses is a method call for the previously created mockito-mock or spy, which is just a fancy proxy class of the class, not a real instance of the class. Proxies have special logic that intercepts a call to a fake proxy method and basically adds this to the list of registered proxy method requests (it is stored in something called IOngoingStubbing
or something like that) for later use. Since Java evaluates the parameters before calling the method, this ensures that the proxy server call is registered / remembered before the when()
method is actually executed. What does when()
does is push this IOngoingStubbing, which then becomes the object that thenReturns()
is called thenReturns()
.
You do not use this โcorrectlyโ, but it still works for you. How? Well, all that should happen is that the proxy method must be called to register with IOngoingStubbing
before when()
is executed. You do not directly call the method on the proxy server, but you indirectly call the method on the proxy server, passing Method.invoke()
to the proxy server. Consequently, the criteria are satisfied, and when()
already has a proxy invocation method registered with IOngoingStubbing
.
You can see the same โrandomโ happiness in the following code, which at first seems pointless until you understand how Mockito works:
@Test public void testSomething() throws Exception { List listMock = mock(List.class); Method m = List.class.getDeclaredMethod("get", int.class); m.invoke(listMock, Mockito.anyInt()); when(null).thenReturn("Hello World");
The above test really passes! Although the when
argument is NULL, the point is that the proxy instance (that is, mock) had the correct method that was called on it before the when
statement was called.
While it is unlikely that Mockito will change the basic way of working under covers, there is still the potential for it to break for you sometime in the future. As I said, it is more or less a fluke that it works. As long as you understand how it works, and the risk associated with it, you have more strength.