Search code examples
javamockitoserviceloader

In Java, how can I mock a service loaded using ServiceLoader?


I have a legacy Java application that has code something like this

ServiceLoader.load(SomeInterface.class)

and I want to provide a mock implementation of SomeInterface for this code to use. I use the mockito mocking framework.

Unfortunately I am unable to change the legacy code, and I do not wish to add anything statically (eg. adding things to META-INF).

Is there an easy way to do this from within the test, ie. at runtime of the test?


Solution

  • You can use PowerMockito along with Mockito to mock static methods:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(ServiceLoader.class)
    public class PowerMockingStaticTest
    {
        @Mock
        private ServiceLoader mockServiceLoader;
    
        @Before
        public void setUp()
        {
            PowerMockito.mockStatic(ServiceLoader.class);
            Mockito.when(ServiceLoader.load(Mockito.any(Class.class))).thenReturn(mockServiceLoader);
        }
    
        @Test
        public void test()
        {
            Assert.assertEquals(mockServiceLoader, ServiceLoader.load(Object.class));
        }
    }