Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking singleton with PowerMockito

in order to test one of the private method I coded, I need to mock a Singleton.

After testing several methods with PowerMockito :

PowerMockito.mockStatic(UtilDatabaseSoldeAutoCdeCommon.class);
Mockito.when(UtilDatabaseSoldeAutoCdeCommon.getInstance()).thenReturn(mockDatabase);

I could never mock this class. Thus I cannot test my methods as in every of them, I access to database.

UtilDatabaseSoldeAutoCdeCommon is defined as such :

public class UtilDatabaseSoldeAutoCdeCommon extends AbstractUtilDatabase {

private static UtilDatabaseSoldeAutoCdeCommon instance;

private UtilDatabaseSoldeAutoCdeCommon() {
    super();
}

public static UtilDatabaseSoldeAutoCdeCommon getInstance() {
    if(instance == null) {
        instance = new UtilDatabaseSoldeAutoCdeCommon();
    }
    return instance;
}

...
}

I debugged powermockito when it calls getInstance() but everytime consructor is called, it crashes as it tries to load configuration file (which does not exist).

I precise that config file is defined as a constant in absract parent class of UtilDatabaseEnrichissement and used in constructor.

How could I test this part ?

like image 531
Biologeek Avatar asked May 04 '16 07:05

Biologeek


People also ask

Can we mock Singleton?

If you are using Mockito 3.4. 0+, you may mock a singleton like the following, without PowerMock or other dependencies.

Can we use both Mockito and PowerMock together?

Of course you can – and probably will – use Mockito and PowerMock in the same JUnit test at some point of time.

Can we mock private methods using PowerMockito?

PowerMock integrates with mocking frameworks like EasyMock and Mockito and is meant to add additional functionality to these – such as mocking private methods, final classes, and final methods, etc. It does that by relying on bytecode manipulation and an entirely separate classloader.


2 Answers

I think this should work:

    @PrepareForTest({UtilDatabaseSoldeAutoCdeCommon.class})
    public class SomeTest {
        @Mock
        UtilDatabaseSoldeAutoCdeCommon fakeSingletonInstance;   

        @Test
        public void test() {
             Whitebox.setInternalState(UtilDatabaseSoldeAutoCdeCommon.class, "instance", fakeSingletonInstance);
             // Write here your test
        }
    }
like image 101
asch Avatar answered Sep 21 '22 16:09

asch


This question was asked long time back and I was facing similar issue and unable to find good answers hence answering it now. I tested the class with suppressing constructor like

PowerMockito.suppress(UtilDatabaseSoldeAutoCdeCommon.class.getConstructors());

like image 26
Mahesh Avatar answered Sep 17 '22 16:09

Mahesh