Issue
I have a class named SpecialClass
. This class has the method doSomething
in it. This class is in this particular manner special, that I do not want to mock this class at all via MockedStatic
. It is very easy for me to remeber that I don't want to mock this class, but there are other people programming at the same project and they should know to not mock this class but I can not relate on it.
Given this special test:
@Test
void testSomething(){
try(MockedStatic<SpecialClass> mock = Mockito.mockStatic(SpecialClass.class)){
mock.when(SpecialClass::doSomething).thenReturn(0);
System.out.println(SpecialClass.doSomething());
}
}
I dont want to let this test execute at all. But it will execute, because Mockito does not know about my SpecialClass and not to mock it. There could be also various other locations where SpecialClass could be mocked.
Some classes can not be mocked because of Mockito decides so. Given this mock of java.lang.System
:
@Test
void testFail(){
try(MockedStatic<System> sys = Mockito.mockStatic(System.class)){
// some code
}
}
I get the exception org.mockito.exceptions.base.MockitoException: It is not possible to mock static methods of java.lang.System to avoid interfering with class loading what leads to infinite loops
, which is ok.
My question is: Can I somehow have some global project settings (or some annoations) to mark my class SpecialClass
to be not used in Mockitos MockedStatic
? I would be also ok if I can also not mock this class in a normal way.
I tried to find some information regarding restricting mocks, but i was unable to find some.
My mockito version of mockito-core and mockito-inline is 4.3.1
Solution
I used a junit test to read all my files and trying to detect all mocks. Please note that my test is working in a very special assumption that all of my test classes are in the same directory. This will hoever not be given in every project. In this case you will need to find the files recursivly.
class NoStaticMockTest {
@Test
void testNoMocks() throws IOException {
// Base dir of my tests
File testDir = new File("src/test/java");
// reading all Files in the test directory excluding this file
for (File file : testDir.listFiles(pathname -> !pathname.getAbsolutePath().endsWith("NoStaticMockTest.java") && pathname.isFile())) {
try (FileInputStream fis = new FileInputStream(file)) {
// Reading the contennt and trying to find MockedStatic<SpecialClass>
String content = IOUtils.toString(fis);
if (content.contains("MockedStatic<SpecialClass>")) {
Assertions.fail(file.getAbsolutePath() + " used MockedStatic<SpecialClass> which is not allowed");
}
}
}
}
}
Answered By - alea
Answer Checked By - Pedro (JavaFixing Volunteer)