Reputation: 1100
I have a problem like this
public class ErrorLog {
public static void increment(String exception) {
// do something
}
}
import ErrorLog;
public class Calculator {
public int division(int a, int b) {
if (b == 0) {
ErrorLog.increment("Divide by Zero");
} else {
return a / b;
}
}
}
I want to verify the number of calls to divide, but when I have divide by zero situation, somehow verify that the static method ErrorLog.increment is called (with the exact string as the parameter).
With Mockito spy, I can do something like this to ensure calls to the divide method.
Calculator c = new Calculator();
Calculator calcSpy = spy(c);
c.division(6, 3);
c.division(1, 0);
verify(calcSpy, times(2)).division(anyInt(), anyInt());
I also keen to verify something like this
verify(ErrorLog, times(1)).increment("Divide by Zero");
I explored PowerMockito verifyStatic constructs and mockStatic, checked this one too mockito verify method call inside method but in my case the method that is called inside the object is static.
Upvotes: 1
Views: 586
Reputation: 1100
Thanks for the responses, it guided me in the right direction. The thing that did the trick to me is this (I am using TestNG framework).
package com.apple.sample.powermock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@PrepareForTest({ErrorLog.class})
public class TestStaticMethods extends PowerMockTestCase {
@Test
public void testSpy() throws Exception {
PowerMockito.mockStatic(ErrorLog.class, invocation -> {
assertEquals("Division by Zero", invocation.getArgument(0, String.class));
return null;
});
new Math().division(10, 0);
}
}
Upvotes: 0
Reputation: 344
you are right. If you use a static method you will have problems with tests and dependency injection and this is a case.
You should transform the ErrorLog in a Singleton and then you could verify it with spy. ex:
public class ErrorLog {
private static ErrorLog = new ErrorLog();
public static ErrorLog getInstance() {
return errorLog;
}
public void increment(String exception) {
// do something
}
}
import ErrorLog;
public class Calculator {
public int division(int a, int b) {
if (b == 0) {
ErrorLog.getInstance()increment("Divide by Zero");
} else {
return a / b;
}
}
}
And from this point you can you the following snippet to test the invocations:
ErrorLog errorLog = ErrorLog.getInstance();
ErrorLog errorLogSpy = spy(errorLog);
verify(errorLogSpy , times(1)).increment(any());
Upvotes: 1
Reputation: 27058
You are right verifyStatic
doesn't have any ways to check the method being called.
But there is a workaround. See if this works for you.
The way to mock a static method is to use
PowerMockito.mockStatic(ErrorLog.class)
But you can also use another variant
PowerMockito.mockStatic(ErrorLog.class, invocationOnMock -> {
assertEquals("something", invocationOnMock.getArgumentAt(0, String.class));
return null;
});
ErrorLog.increment("something");
If you do not mock ErrorLog class, you cannot verify
Upvotes: 1