Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative of mocking a static method present in some jar

I know that if I need to mock a static method, this indicates that my design has some issue, but in my case this does not seem to be a design issue.

BundleContext bundleContext = FrameworkUtil.getBundle(ConfigService.class).getBundleContext();

Here FrameworkUtil is a class present in an api jar. Using it in code cant be a design issue.

my problem here is while running this line

FrameworkUtil.getBundle(ConfigService.class); 

returns null So my question, is there any way by which I can replace that null at runtime I am using Mockito framewrok and my project does not allow me to use powermock.

if I use

doReturn(bundle).when(FrameworkUtil.class)

in this way getBundle method is not visible since its a static method.

like image 855
ankit Avatar asked Dec 20 '22 21:12

ankit


1 Answers

You are correct that is not a design issue on your part. Without PowerMock, your options become a bit murkier, though.

I would suggest creating a non-static wrapper for the FrameworkUtil class that you can inject and mock.

Update: (David Wallace)

So you add a new class to your application, something like this

public class UtilWrapper {
    public Bundle getBundle(Class<?> theClass) {
        return FrameworkUtil.getBundle(theClass);
    }
}

This class is so simple that you don't need to unit test it. As a general principle, you should only EVER write unit tests for methods that have some kind of logic to them - branching, looping or exception handling. One-liners should NOT be unit tested.

Now, within your application code, add a field of type UtilWrapper, and a setter for it, to every class that currently calls FrameworkUtil.getBundle. Add this line to the construtor of each such class

utilWrapper = new UtilWrapper();

And replace every call to FrameworkUtil.getBundle with utilWrapper.getBundle.

Now in your test, you make a mock UtilWrapper and stub it to return whatever Bundle you like.

when(mockUtilWrapper.getBundle(ConfigService.class)).thenReturn(someBundleYouMade);

and for the class that you're testing, call setUtilWrapper(mockUtilWrapper) or whatever. You don't need this last step if you're using @InjectMocks.

Now your test should all hang together, but using your mocked UtilWrapper instead of the one that relies on FrameworkUtil.

like image 89
Dave Avatar answered Mar 16 '23 17:03

Dave