How to mock static factory method using Mockito

86 views Asked by At

Following is my class where I need to mock "resourceManager.getLicenseSources(licenseId)", how this can be achieved?

class LicenseSourceImpl{
-----
ResourceManager resourceManager = ManagerFactory.getInstance(ResourceManager.class);
List<Source> sources = resourceManager.getLicenseSources(licenseId);
-----
}

Few things I've tried:

  1. Mock ManagerFactory itself

    ManagerFactory mf = Mockito.mock(ManagerFactory.class); Mockito.when(mf.getInstance(any())).thenReturn(resourceManager); Mockito.when(resourceManager.getLicenseSources(LICENSE_ID)).thenReturn(sources);

This fails with java.lang.NullPointerException: Cannot invoke "java.lang.Class.getName()" because "clazz" is null

  1. Mock ManagerFactory and static mock

    ManagerFactory mf = Mockito.mock(ManagerFactory.class); Mockito.when(mf.getInstance(ResourceManager.class)).thenReturn(resourceManager); Mockito.when(resourceManager.getLicenseSources(LICENSE_ID)).thenReturn(sources);

This fails with

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);
  1. Spy on factory static method ResourceManager resourceManager = spy(ManagerFactory.getInstance(ResourceManager.class)); but this not mocking the factory instance and creates a new instance always

Is there a way to mock for these situations?

2

There are 2 answers

0
Per Huss On

You would have to use Mockito.mockStatic to mock a static method. See Mockito javadoc on how to do it. But better design would be to avoid accessing the static factory in your class but rather have the ResourceManager injected, so that you can inject a regular mock in your test...

0
ivanoklid On

You can follow this link to see how you can mock a static method https://www.baeldung.com/mockito-mock-static-methods

You can use

try (MockedStatic<ResourceManager> resourceManagerMock = Mockito.mockStatic(ResourceManager.class)) {
}