I need to mock a static method, so that it throws an exception the first time it is called, and returns some value, the second time it is called. I know how to mock it so that it throws an exception and mock it so that it returns a value, but am not sure how to make it behave differently on two subsequent calls.
Also, how would I test two subsequent calls to a mocked static method in a single test? Would I be able to do it in one MockedStatic block or do I need two separate Mocked static blocks for each call? This question will make more sense in the example below:
/** Util class containing static. method to be mocked */
public final class VariableUtil {
//. static method to be mocked.
public static JsonValue createJsonVariable(Object variableValue) throws Exception{…..}
}
/** JsonValue class */
public interface JsonValue extends PrimitiveValue<String> {
}
/** Class that uses the VariableUtil class */
public class SomeClass {
//. Method that makes two calls to the static method.
public void someMethod() {
try {
//. Make the FIRST call to the static method.
//. This time it SHOULD throw an exception
VariableUtil.createVariable(
Collections.singletonList(someObject));
} catch(Exception ex) {
//. The first call’s exception should bring execution into
//. this catch block, where we,
//. make the SECOND call to the static method. This time
//. it SHOULD NOT throw an exception and instead return a mocked value.
JsonValue someJsonValue = VariableUtil.createVariable(
Collections.singletonList(someObject));
}
}
}
/**.JUnit.*/:
@Test
public void testCreateVariable() {
//. The below DOES NOT WORK. How would I mock it so that,
//. on the first invocation, it throws an Exception
//. and, on the second, it returns a value?
try (final MockedStatic<VariableUtil> variableUtilMock =
//. Mock throwing an exception.
mockStatic(VariableUtil.class)) {
variableUtilMock.when(() -> VariableUtil.createJsonVariable(processingFailureErrorMessage))
.thenThrow(new Exception());
//. Mock returning a value.
variableUtilMock.when(() -> VariableUtil.createJsonVariable(processingFailureErrorMessage))
.thenReturn("someJsonValue");
SomeClass someObject = new SomeClass();
someObject.someMethod();
}
}
2
You have to chain the thenThrow
/thenReturn
calls if you want consecutive calls (with same arguments) to return different values.
If you don’t chain, earlier stubbings are overwritten.
variableUtilMock.when(() -> VariableUtil.createJsonVariable(processingFailureErrorMessage))
.thenThrow(new Exception())
.thenReturn("someJsonValue");
See Stubbing consecutive calls in the Mockito docs.