Search code examples
unit-testingmockingtestngpowermockeasymock

Why do I have to extend PowerMockTestCase?


The below test throws java.lang.IllegalStateException: no last call on a mock available when I don't extend from the PowerMockTestCase.

The error disappears as soon as I extend from PowerMockTestCase. Why exactly is this happening?

import static org.junit.Assert.assertEquals;

import org.easymock.EasyMock;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;

@PrepareForTest({ IdGenerator.class, ServiceRegistartor.class })
public class SnippetTest extends PowerMockTestCase{

    @org.testng.annotations.Test
    public void testRegisterService() throws Exception {
        long expectedId = 42;

        // We create a new instance of test class under test as usually.
        ServiceRegistartor tested = new ServiceRegistartor();

        // This is the way to tell PowerMock to mock all static methods of a
        // given class
        PowerMock.mockStatic(IdGenerator.class);

        /*
         * The static method call to IdGenerator.generateNewId() expectation.
         * This is why we need PowerMock.
         */
        EasyMock.expect(IdGenerator.generateNewId()).andReturn(expectedId).once();

        // Note how we replay the class, not the instance!
        PowerMock.replay(IdGenerator.class);

        long actualId = tested.registerService(new Object());

        // Note how we verify the class, not the instance!
        PowerMock.verify(IdGenerator.class);

        // Assert that the ID is correct
        assertEquals(expectedId, actualId);
    }

}

Solution

  • While using PowerMock for static mocking, there is a class level instrumentation happening to make your mocking work. PowerMockTestCase class has a code (method beforePowerMockTestClass()) to switch your regular class loader to powermock class loader which orchestrates mocking injection. Hence you need to extend this class for static mock to work.