使用PowerMock在静态块中模拟getResource

时间:2017-12-17 09:46:53

标签: java unit-testing junit powermock static-block

如何在静态块中模拟getResourceAsStream? 我认为这是不可测试的。

我审核了SO,但找不到答案。 closes-SO-post-here无法解决问题,因为帖子中对getResourceAsAStream的调用不是来自静态块

我尝试过PowerMock,并遇到了许多限制。首先,如果我想模拟SomeProperties.class.getResourceAsStream - 静态块将执行,因为我需要引用类本身。我可以抑制静态阻止以防止这样做,但这将阻止我完全执行静态块。解决方案是推迟静态块的执行,直到someproperties.class.getResourceAsStream被模拟为止。 我不认为这是可能的。 似乎这段代码纯粹是不可测试的; 还有其他想法吗?

以下是代码 [and a link to GITHUB]

package com.sopowermock1;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class SomeProperties {

    private static Properties props = new Properties();

    static {
        InputStream is = SomeProperties.class.getResourceAsStream("/some.properties");

        try {
            props.load(is);
            System.out.println("Properties.props.keySet() = " + props.keySet());            
        } catch (IOException e) {
            // How test this branch???
            System.out.println("Yes. We got here.");
            throw new RuntimeException(e);
        }
    }

    private SomeProperties() {}; // to makes life even harder...

    public static String getVersion() {
        return props.getProperty("version");
    }
}

这是测试GITHUB Link

package com.sopowermock1;
import java.io.InputStream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.sopowermock1.SomeProperties;

@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeProperties.class)

// This will prevent running static block completely:
// @SuppressStaticInitializationFor("com.sopowermock1.SomeProperties")
public class SomePropertiesTest {

    @Mock
    private static InputStream streamMock;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(SomeProperties.class);
        System.out.println("test setUp");
    }

    @Test(expected = RuntimeException.class)
    public void testStaticBlock() {

        PowerMockito.mockStatic(SomeProperties.class); // this will mock all static methods (unwanted as we want to call getVersion)

        // This will cause static block to be called.
        PowerMockito.when(SomeProperties.class.getResourceAsStream("/some.properties")).thenReturn(streamMock);
        SomeProperties.getVersion();
    }
}

有什么想法吗?完整的GITHUB源是here

1 个答案:

答案 0 :(得分:0)

How to mock getResourceAsStream method using PowerMockito and JUnit?中所述

,使用提取委托,然后模拟委托类,例如 XXStreamFetcher ,然后可以对其进行测试。