During mockStatic
definition in Mockito you can specify setting to perform real execution by default Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS)
. In this way, your static mock will work like Spy
.
Let's create simple Utils
class for testing.
public class Utils {
public static String method1() {
return "Original mehtod1() value";
}
public static String method2() {
return "Original mehtod2() value";
}
public static String method3() {
return method2();
}
}
Make mock for method2
and perform real execution of method1
and method3
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
public class SpyStaticTest {
@Test
public void spy_static_test() {
try (MockedStatic<Utils> utilities = Mockito.mockStatic(Utils.class, Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS))) {
utilities.when(Utils::method2).thenReturn("static mock");
Assertions.assertEquals(Utils.method1(), "Original mehtod1() value");
Assertions.assertEquals(Utils.method2(), "static mock");
Assertions.assertEquals(Utils.method3(), "static mock");
}
}
}
Example for your class:
@Test
public void test() {
try (MockedStatic<MessageValidationUtils> utilities = Mockito.mockStatic(MessageValidationUtils.class, Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS))) {
utilities.when(() -> MessageValidationUtils.validateTelegramKeyMap(messageProcessDto.getMessageMessageType(),
messageProcessDto.getMessageKeyValueMap())).thenAnswer((Answer<Boolean>) invocation -> true);
//perform testing of your service which uses MessageValidationUtils
}
}
UPDATE:
Example to use mockStatic
in @BeforeEach
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
public class SpyStaticTest {
MockedStatic<Utils> utilities;
@BeforeEach
public void setUp() {
utilities = Mockito.mockStatic(Utils.class, Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
}
@Test
public void spy_static_test1() {
utilities.when(Utils::method2).thenReturn("static mock");
Assertions.assertEquals(Utils.method1(), "Original mehtod1() value");
Assertions.assertEquals(Utils.method2(), "static mock");
Assertions.assertEquals(Utils.method3(), "static mock");
}
@Test
public void spy_static_test2() {
utilities.when(Utils::method1).thenReturn("static mock");
Assertions.assertEquals(Utils.method1(), "static mock");
Assertions.assertEquals(Utils.method2(), "Original mehtod2() value");
Assertions.assertEquals(Utils.method3(), "Original mehtod2() value");
}
@AfterEach
public void afterTest() {
utilities.close();
}
}
UPDATE:
Mockito does not provide method for static Spy
creation, but you can define own utils and implemet spy static definition there.
import org.mockito.MockedStatic;
import org.mockito.Mockito;
public class MockitoUtils {
public static <T> MockedStatic<T> spyStatic(Class<T> classToMock) {
return Mockito.mockStatic(classToMock, Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
}
}
In this way your tests will look more clear:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static com.test.MockitoUtils.spyStatic;
public class SpyStaticTest {
MockedStatic<Utils> utilsSpy;
@BeforeEach
public void setUp() {
utilsSpy = spyStatic(Utils.class);
}
@Test
public void spy_static_test1() {
utilsSpy.when(Utils::method2).thenReturn("static mock");
Assertions.assertEquals(Utils.method1(), "Original mehtod1() value");
Assertions.assertEquals(Utils.method2(), "static mock");
Assertions.assertEquals(Utils.method3(), "static mock");
}
@Test
public void spy_static_test2() {
utilsSpy.when(Utils::method1).thenReturn("static mock");
Assertions.assertEquals(Utils.method1(), "static mock");
Assertions.assertEquals(Utils.method2(), "Original mehtod2() value");
Assertions.assertEquals(Utils.method3(), "Original mehtod2() value");
}
@AfterEach
public void afterTest() {
utilsSpy.close();
}
}