首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >临时工 - PowerMock系列4

临时工 - PowerMock系列4

作者头像
Antony
发布于 2020-12-01 09:38:23
发布于 2020-12-01 09:38:23
1.3K0
举报

测试场景

在测试过程中,发现我们的开发同学喜欢在方法中临时new 出一些类来完成某项工作。由于局部变量用完立即销毁了,使用起来也就非常灵活和随意了。 但这样就对单元测试造成了不小的麻烦。如以下的案例

代码语言:javascript
复制
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ReaderDemo {
public static String read(String path) throws IOException {
String result = "";
InputStream in = new FileInputStream(path);
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
for (String line = br.readLine(); line != null; line = br.readLine()) {
result+=line;
}
isr.close();
return result;
}
}

FileInputStream、InputStreamReader、BufferedReader都是在read方法的执行过程中临时new出来的,无法通过ReaderDemo的构造方法或者修改成员变量等方式进行注入。

解决方法

幸好Powermock提供了whenNew这样一个Mock方法,可以解决上述临时变量的问题。demo案例的测试用例如下

代码语言:javascript
复制
import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ ReaderDemo.class })
public class ReaderDemoTest {
    @Test
    public void doSomethingReturnsValueFromBufferedReader() throws Exception {
        InputStreamReader inputStreamReaderMock = mock(InputStreamReader.class);
        BufferedReader bufferedReaderMock = mock(BufferedReader.class);
        FileInputStream inputStreamMock= mock(FileInputStream.class);
        PowerMockito.whenNew(BufferedReader.class).
                    withArguments(inputStreamReaderMock).
                    thenReturn(bufferedReaderMock);
        PowerMockito.whenNew(FileInputStream.class).
        withAnyArguments().
        thenReturn(inputStreamMock);

      PowerMockito.whenNew(InputStreamReader.class).
                    withAnyArguments().thenReturn(inputStreamReaderMock);
        final String string = "key=value\n";
      doReturn(string).doReturn(null).when(bufferedReaderMock).readLine();
        // read && Assert
        assertEquals(string, ReaderDemo.read("anything"));
    }
}

记得第二次调用readLine()时返回null,不然就死循环了。

临时工,不背锅

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-05,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 测试场景
  • 解决方法
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档