Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito - intercept any method invocation on a mock

Is it possible to intercept all method invocations on a mock in a generic way?

Example

Given a vendor provided class such as:

public class VendorObject {      public int someIntMethod() {         // ...     }      public String someStringMethod() {         // ...     }  } 

I would like to create a mock that re-directs all method calls to another class where there are matching method signatures:

public class RedirectedToObject {      public int someIntMethod() {         // Accepts re-direct     }  } 

The when().thenAnswer() construct in Mockito seems to fit the bill but I cannot find a way to match any method call with any args. The InvocationOnMock certainly gives me all these details anyway. Is there a generic way to do this? Something that would look like this, where the when(vo.*) is replaced with appropriate code:

VendorObject vo = mock(VendorObject.class); when(vo.anyMethod(anyArgs)).thenAnswer(     new Answer() {         @Override         public Object answer(InvocationOnMock invocation) {              // 1. Check if method exists on RedirectToObject.             // 2a. If it does, call the method with the args and return the result.             // 2b. If it does not, throw an exception to fail the unit test.          }     } ); 

Adding wrappers around the vendor classes to make mocking easy is not an option because:

  1. Too large an existing code base.
  2. Part of extremely performance critical applications.
like image 706
Karle Avatar asked May 31 '12 18:05

Karle


1 Answers

I think what you want is:

VendorObject vo = mock(VendorObject.class, new Answer() {     @Override     public Object answer(InvocationOnMock invocation) {          // 1. Check if method exists on RedirectToObject.         // 2a. If it does, call the method with the args and return the         // result.         // 2b. If it does not, throw an exception to fail the unit test.      } }); 

Of course, if you want to use this approach frequently, no need for the Answer to be anonymous.

From the documentation: "It's quite advanced feature and typically you don't need it to write decent tests. However it can be helpful when working with legacy systems." Sounds like you.

like image 184
jhericks Avatar answered Sep 20 '22 23:09

jhericks