【问题标题】:How to mock getResourceAsStream method using PowerMockito and JUnit?如何使用 PowerMockito 和 JUnit 模拟 getResourceAsStream 方法?
【发布时间】:2016-08-11 20:48:47
【问题描述】:

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

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

对于 mock 框架,我更喜欢 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 不返回模拟。我该如何解决?

【问题讨论】:

    标签: junit powermock powermockito


    【解决方案1】:

    您可以将资源抽象化到一个类中。

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

    在你的班级里

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

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

    您实际上还可以抽象更多内容,并可能以某种方式处理 Stream。我不了解业务背景,因此无法真正帮助您。

    【讨论】:

      【解决方案2】:

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

      Connector.class.getResourceAsStream(...)
      

      它调用

      Conn.class.getResourceAsStream(...)
      

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

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

      【讨论】:

        【解决方案3】:

        你可以这样做:

            @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") 的方法,它工作正常(我已经测试过)。

        【讨论】:

          猜你喜欢
          • 2017-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-07
          • 1970-01-01
          • 2015-03-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多