如何断言OutputStreamWriter包含正确的GZIPOutputStream或FileOutputStream实例
解决方案
你可以通过两种常用方式实现断言,各有优劣可以按需选择:
方法1:反射读取内部私有字段验证(无需修改业务代码)
OutputStreamWriter会把传入的输出流封装到内部的StreamEncoder实例中,我们可以通过两层反射拿到最终的底层流,直接验证类型:
- 封装反射工具方法:
import java.io.OutputStream; import java.io.OutputStreamWriter; import java.lang.reflect.Field; public static OutputStream getInnerOutputStream(OutputStreamWriter writer) throws Exception { // 第一层:读取OutputStreamWriter持有的StreamEncoder实例 Field seField = OutputStreamWriter.class.getDeclaredField("se"); seField.setAccessible(true); Object streamEncoder = seField.get(writer); // 第二层:读取StreamEncoder持有的底层输出流 Field outField = streamEncoder.getClass().getDeclaredField("out"); outField.setAccessible(true); return (OutputStream) outField.get(streamEncoder); }
- 单元测试断言示例:
import org.junit.Test; import java.io.File; import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.zip.GZIPOutputStream; import static org.junit.Assert.assertTrue; @Test public void testGzFileReturnGzipStream() throws Exception { File testGz = File.createTempFile("test", ".gz"); try { OutputStreamWriter writer = (OutputStreamWriter) 你的目标方法(testGz); OutputStream innerStream = getInnerOutputStream(writer); // 验证是GZIPOutputStream类型 assertTrue(innerStream instanceof GZIPOutputStream); // 如需验证GZIP内层是文件输出流,继续反射读取FilterOutputStream的out字段即可 Field gzipOutField = FilterOutputStream.class.getDeclaredField("out"); gzipOutField.setAccessible(true); OutputStream gzipInner = (OutputStream) gzipOutField.get(innerStream); assertTrue(gzipInner instanceof FileOutputStream); } finally { testGz.delete(); } } @Test public void testNormalFileReturnFileStream() throws Exception { File testTxt = File.createTempFile("test", ".txt"); try { OutputStreamWriter writer = (OutputStreamWriter) 你的目标方法(testTxt); OutputStream innerStream = getInnerOutputStream(writer); assertTrue(innerStream instanceof FileOutputStream); } finally { testTxt.delete(); } }
注意:该方法依赖JDK内部实现,不同厂商/版本的JDK可能字段名有差异,兼容性稍差
方法2:黑盒验证写入结果(兼容性更强)
不需要依赖JDK内部实现,直接通过实际写入内容的格式验证流类型:
- 对于.gz后缀文件:往返回的Writer中写入测试字符串,关闭后用
GZIPInputStream读取该文件,能正常解压出和写入一致的内容,就说明内层是GZIPOutputStream - 对于普通文件:直接读取文件内容和写入内容一致,说明是普通
FileOutputStream
这种方法更符合单元测试的黑盒原则,不受JDK版本影响,稳定性更高。
内容的提问来源于stack exchange,提问作者Poli
相关产品推荐
相关产品推荐

