Mockito: is it possible to combine mock with the method name to create a Call method inside the when () call?

my first question is about stackoverflow. I would like to be able to do something like:

SomeClass mock = mock (SomeClass.class);

String methodName = "someMethod"; OR Method Method = ... someMethod ...

Both of these things (layout and method) came together to do the following:

when (mock.someMethod ()) thenReturn (zero) ;. Strong>

Of course, the value "null" will be changed accordingly for my needs, but I am trying to define two things:

1) Is it possible to do something like this in Java? This = the union of the class object and method in the Call method.

2) How do I do this?

I have explored this endlessly, and I cannot find anything. The problem is that even if this works with the regular class and the regular method (someClass and someMethod come together to make someClass.someMethod ()), keep in mind that this should work with the mock object for use inside the when () call.

ANSWERED: when (method.invoke (mock)). thenReturn ("Hello world."); this is the correct syntax, and reflection really works inside the when () call. Thank Kevin Welker

+6
source share
2 answers

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"); // Huh? passing null? assertEquals("Hello World", listMock.get(0)); // works! } 

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.

+7
source

I think adding a new method after class initialization is not possible if the method is not specified in the interface or class provided by Mockito. You would change the class signature after initialization, and that is not possible.

For calls to the stub method, see: http://code.google.com/p/mockito/ . There is a pattern on method call stubs.

If you want dynamic responses, not static ones, you should not use Mockito. Use a fake object or stub to get behavior for testing. See http://martinfowler.com/articles/mocksArentStubs.html for more on this issue.

0
source

Source: https://habr.com/ru/post/913037/


All Articles