如何模拟专用于ResourceBundle的私有静态属性

问题描述

我想嘲笑缺少the_function的情况。

message.properties

但是当我尝试时:

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

我也尝试了其他方法,但是我总是得到@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")); } }

解决方法

我会遵循以下内容(注意-模拟静态方法需要Mockito 3.4.x)

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);
            }
        }
    }
}

与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,"key"));
            var underTest = new ClassToTest();
        } catch (ExceptionInInitializerError ex) {
            Assert.assertEquals(MissingResourceException.class,ex.getCause().getClass());
            Assert.assertEquals(exMessage,ex.getCause().getMessage());
        }
    }
}