Issue
I have a test which worked using spring and mockito
@Test
@WebAppConfiguration
@ContextConfiguration(classes = { MockConfiguration.class }, loader = AnnotationConfigWebContextLoader.class)
@ActiveProfiles(profiles = { "mock" })
public class TestMock extends AbstractTestNGSpringContextTests {
@Autowired
private ApplicationContext context;
@Test
public void testRule() {
// test code calling context.getBean
}
}
The problem after code changes the test is now using the following POJO which calls static getSingleton
method which returns null
public class Rule {
private MyObject myObject;
public Rule(int id) {
myObject = Cache.getSingleton().getObjectCache().getObjectById(id);
}
}
Can I mock it without any code changes?
Solution
Mockito has enabled mocking static methods since version 3.4.0, so if you're using a matching or newer version, you can use it. See the docs.
It would look like this:
// create mocks
Cache mockedCache = mock(Cache.class);
ObjectCache objectCache = mock(ObjectCache.class);
MyObject myObject = new MyObject();
// define the non-static behavior for the mocks
when(mockedCache.getObjectCache())
.thenReturn(objectCache);
when(objectCache.getObjectById(anyInt()))
.thenReturn(myObject);
// mock static call: Cache.getSingleton()
try (MockedStatic mocked = mockStatic(Cache.class)) {
mocked.when(Cache::getSingleton)
.thenReturn(mockedCache);
// run rest of the test
}
It would be best to avoid mocking static methods and try to resolve it otherwise, e.g. add an object to the cache before executing the actually tested code, but if it's not possible - use the example above.
Answered By - Jonasz
Answer Checked By - David Marino (JavaFixing Volunteer)