Mocking a final method with PowerMock + EasyMock

easymock, powermock

Solution

You are creating an instance using EasyMock. Instead, when working with static methods, you must mock the class (using PowerMock).

It should work like that (tested with EasyMock 3.0 and PowerMock 1.5, though):

@RunWith(PowerMockRunner.class)
@PrepareForTest(ResourceBundle.class) 
public class TestSuite {
    @Before
    public void setUp() throws Exception {
        // mock the class for one method only
        PowerMock.mockStaticNice(ResourceBundle.class, "getString");

        // define mock-behaviour on the class, when calling the static method
        expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue");

        // start the engine
        PowerMock.replayAll();
    }
}

(I'm aware this question is a few months old, but it might help others, though)

Problem

I'm trying to mock a call to the final method `ResourceBundle.getString()`. With PowerMock 1.4.12 and EasyMock 3.1, the call is not being mocked; instead, the "real" method is called. My test class: ``` @RunWith(PowerMockRunner.class) @PrepareForTest(ResourceBundle.class) public class TestSuite { @Before public void setUp() throws Exception { ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class); expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue"); PowerMock.replay(resourceBundleMock); beanBeingTested.setMessages(resourceBundleMock); } ... } ``` Code in BeanBeingTested: ``` private ResourceBundle messages; ... String label = messages.getString(BundleConstants.QUEUE); ``` Error message: ``` java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue at java.util.ResourceBundle.getObject(ResourceBundle.java:384) at java.util.ResourceBundle.getString(ResourceBundle.java:344) at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87) ``` When I step through the test case, the debugger shows the type of `beanBeingTested.messages` as "EasyMock for class java.util.ResourceBundle", so the mock is injected correctly. (Also, there's no error on the call to `getString()` within the `expect()` call during set up). With a plain mock instead of a nice mock, I get the following error: ``` java.lang.AssertionError: Unexpected method call handleGetObject("Queue"): getString("Queue"): expected: 1, actual: 0 ``` Any idea what I'm doing wrong? Thanks.

Original source