How to mock a private static property, specially for ResourceBundle

Viewed 875

I want to mock the situation when missing message.properties.

public class ClassToTest{
    private static ResourceBundle bundle = ResourceBundle.getBundle("message");
    public static String getMessage(String key){
        return bundle.getString(key);
    }
}

But when I tried :

@RunWith(PowerMockRunner.class)
@PrepareForTest(ResourceBundle.class)
public class ClassToTestTest{

    @Test
    public void myTest(){
        PowerMockito.spy(ResourceBundle.class);
        PowerMockito.when(ResourceBundle.class, "getBundle").thenThrow(new Exception("missing message.properties"));
    }

}

I've also tried other ways, but I always get NoClassDefFoundError:org/mockito/exceptions/Reporter

1 Answers

I would go with the following (note - Mockito 3.4.x is needed to mock static methods)

public class ClassToTestTest {
    @Test
    public void test() {
        try (MockedStatic<ResourceBundle> dummyStatic = Mockito.mockStatic(ResourceBundle.class)) {
            dummyStatic.when(() -> ResourceBundle.getBundle(anyString()))
                       .thenThrow(new MissingResourceException("s", "className", "key"));
            // when
            try {
                var underTest = new ClassToTest();
            } catch (ExceptionInInitializerError ex) {
                var cause = ex.getCause();
                Assertions.assertEquals(MissingResourceException.class, cause);
            }
        }
    }
}

Same test with PowerMock:

import org.junit.Assert;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.Test;

import java.util.MissingResourceException;
import java.util.ResourceBundle;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassToTest.class})
public class ClassToTestTest {
    @Test
    public void myTest() {
        var exMessage = "m1";
        try {
            PowerMockito.mockStatic(ResourceBundle.class);
            PowerMockito.when(ResourceBundle.getBundle("message"))
                        .thenThrow(new MissingResourceException(exMessage, "className", "key"));
            var underTest = new ClassToTest();
        } catch (ExceptionInInitializerError ex) {
            Assert.assertEquals(MissingResourceException.class, ex.getCause().getClass());
            Assert.assertEquals(exMessage, ex.getCause().getMessage());
        }
    }
}
Related