Mocking Reflection Based Computations

I am trying to make fun of some thought-based methods. Below you can see the details,

Class test

public class TracerLog { @AroundInvoke public Object logCall(InvocationContext context) throws Exception { Logger logger = new Logger(); String message = "INFO: Invoking method - " + context.getMethod().getName() + "() of Class - " + context.getMethod().getDeclaringClass(); logger.write(message); return context.proceed(); } } 

Test

 public class TracerLogTest { @Mock InvocationContext mockContext; @Mock Logger mockLogger; @InjectMocks private TracerLog cut = new TracerLog(); @BeforeMethod public void setup() { MockitoAnnotations.initMocks(this); } @Test public void logCallTest() throws Exception { when(mockContext.proceed()).thenReturn(true); when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass"); cut.logCall(mockContext); verify(mockContext).proceed(); } 

}

or

 @Test public void logCallTest() throws Exception { when(mockContext.proceed()).thenReturn(true); when(mockContext.getMethod().getName()).thenReturn("someMethod"); when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass"); cut.logCall(mockContext); verify(mockLogger).write(anyString()); verify(mockContext).proceed(); } 

But tests are not executed with a NullPointerException. I understand that I am doing something wrong against mocking concepts, but I do not understand what it is. Could you tell us about it and also suggest to me how this method can be tested?

Thanks.

+8
java mockito mocking
source share
2 answers

You need a Method object and a Class object. According to your comment, Mokito cannot scoff at the Method, so you need a real one. I have not tested this, but I believe that it will work. Instead:

 when(mockContext.getMethod().getName()).thenReturn("someMethod"); when(mockContext.getMethod().getDeclaringClass().getName()).thenReturn("someClass"); 

You need:

 // any method will do, but here is an example of how to get one. Method testMethod = this.getClass().getMethod("logCallTest"); when(mockContext.getMethod()).thenReturn(testMethod); 

Obviously, getName() will no longer return "someMethod", but getDeclaringClass().getName() will return the name of this test class (in the example), but although you could not choose what they returned, what they returned is still determinate so that you can verify everything you need. (Of course, if you need to spy on or verify that the call was made on the Method object itself, you get stuck anyway.)

+17
source share

Yes, the problem is that mockContext.getMethod() is going to return null. So every time you run this, then call something based on the result (getDeclaringClass () or getName ()), you will get NPE. You probably want to use the default RETURNS_DEEP_STUBS answer when you customize the layout. Something like

 @Mock( answer = RETURNS_DEEP_STUBS ) private InvocationContext mockContext; 

gotta do the trick.

+3
source share

All Articles