如何使用PowerMockito和JUnit模拟getResourceAsStream方法?

时间:2015-03-13 23:57:26

标签: junit powermock powermockito

我尝试模拟我在构造函数中调用的getResourceAsStream方法。

public Conn() {
    stream = Conn.class.getClass().getResourceAsStream(PATH);
}

对于模拟框架,我更喜欢Mockito + PowerMockito。

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Conn.class)
    public class ConnTest {

        @Mock
        private InputStream streamMock;

        private Conn conn;

        @Before
        public void before() {
            initMocks(this);
        }

        @Test
        public void test() {    
            PowerMockito.mockStatic(Conn.class);
            PowerMockito.when(Connector.class.getResourceAsStream("/prop.properties")).thenReturn(streamMock);
            conn = new Conn();
        }

        @After
        public void after() {
            reset(streamMock);
        }
     }

但方法thenReturn不会返回模拟。我该如何解决?

3 个答案:

答案 0 :(得分:0)

您可以抽象将资源获取到类。

class StreamFetcher {

InputStream fetchStream(String path) {
return StreamFetcher.class.getClass().getResourceAsStream(path);
}

}

并在你的班级

class Conn {
public Conn(StreamFetcher streamFetcher) {
    stream = streamFetcher.fetchStream(PATH);
}
}

这样你甚至不需要做一个模拟 - 你可以为你做任何你需要它做的测试创建你自己的impl。

此外,您实际上可以抽象更多,并可能以某种方式处理流。我不了解业务背景,所以无法真正帮助你。

答案 1 :(得分:0)

它没有返回模拟,因为被测试代码new Conn()没有调用

Connector.class.getResourceAsStream(...)

它调用

Conn.class.getResourceAsStream(...)

您的代码通过将方法存根更改为:

来工作
PowerMockito.when(Conn.class.getResourceAsStream("/prop.properties")).thenReturn(streamMock);

答案 2 :(得分:0)

你可以这样做:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Class.class)
    public class ConnTest {

        @Mock
        private InputStream streamMock;

        private Conn conn;

        @Before
        public void before() {
            initMocks(this);
        }

        @Test
        public void test() {    
            PowerMockito.mockStatic(Class.class);
            PowerMockito.when(Connector.class.getClass().getResourceAsStream("/prop.properties")).thenReturn(streamMock);
            conn = new Conn();
        }

        @After
        public void after() {
            reset(streamMock);
        }
     }

这里是在类对象之上存根资源,这就是为什么Class.class需要使用@PrepareForTest(Class.class)PowerMockito.mockStatic(Class.class);准备测试。

我不确定它是否适用于构造函数,但是对于调用getClass.getResourceAsStream("anyString")的方法,它工作正常(我已经测试过)。