Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 568
Graeme Moss Avatar asked Mar 02 '15 08:03

Graeme Moss


People also ask

What is ServiceLoader in Java?

A service provider (or just provider) is a class that implements or subclasses the well-known interface or class. A ServiceLoader is an object that locates and loads service providers deployed in the run time environment at a time of an application's choosing.

What is service provider class in Java?

A service provider is a specific implementation of a service. The classes in a provider typically implement the interfaces and subclass the classes defined in the service itself.


1 Answers

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));
    }
}
like image 62
esaj Avatar answered Oct 07 '22 01:10

esaj