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