Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling real method in Mockito, but intercepting the result

Simplifying a bit, our system has two parts. "Our" part, which in turn uses an lower level part implemented by another team (in the same codebase). We have a fairly complicated functional test setup, where we wrap the entry points to the lower level in spy objects. In positive tests we use the real implementation of that level, but we mock calls that should fail with some predefined error.

Now I am trying to add support for more complicated scenarios, where I would like to add an artificial delay for the calls made to the underlying level (on a fake clock obviously). To do this I would like to define a mock that would (1) Call the real implementation (2) Get the resulting Future object that is returned and combine it with a custom function that would inject the delay accordingly. So Ideally I would like to have something like:

doAnswer(invocationOnMock -> 
    { 
      result = call real method on mySpy; 
      return Futures.combile(result, myFunction);
    }).when(mySpy).myMethod();

How can I achieve it?

like image 925
Grzenio Avatar asked Aug 23 '17 15:08

Grzenio


People also ask

Does Mockito spy call real method?

A mock does not call the real method, it is just proxy for actual implementations and used to track interactions with it. A spy is a partial mock, that calls the real methods unless the method is explicitly stubbed. Since Mockito does not mock final methods, so stubbing a final method for spying will not help.

How do you call a real method in Mockito?

To call a real method of a mock object in Mockito we use the thenCallRealMethod() method.


1 Answers

As for me the easiest way it's just to save the link to the read object when you initialize your Spy object:

Foo realFoo = new Foo();
Foo spyFoo = Mockito.spy(realFoo);

Now you can stub it like this:

doAnswer(invocation -> realFoo.getSome() + "spyMethod").when(spyFoo).getSome();

One more way is to call invocation.callRealMethod():

doAnswer(invocation -> invocation.callRealMethod() + "spyMethod").when(spyFoo).getSome();

But in this case you may need to cast the return value as long as invocation.callRealMethod() returns Object.

like image 90
Sergii Bishyr Avatar answered Sep 30 '22 18:09

Sergii Bishyr