Mockito JUnit5测试PDF转图片上传Blob时遇IOException求助
问题分析与解决方案
你遇到的PDDocument.load()抛出IOException的问题,通常和测试文件读取、资源管理或依赖冲突有关,下面是具体的排查步骤和完善后的测试用例:
一、常见原因与排查步骤
测试文件读取路径错误
确保测试PDF文件放在src/test/resources目录下,读取时用类路径资源加载(避免绝对路径带来的环境差异)。不要直接用new File("test.pdf"),而是用类加载器获取流:try (InputStream pdfStream = getClass().getResourceAsStream("/sample.pdf")) { if (pdfStream == null) { throw new IllegalArgumentException("测试PDF文件不存在,请检查路径是否正确"); } // 后续加载PDF逻辑 }资源流未正确关闭
必须用try-with-resources语法包裹InputStream和PDDocument,确保资源自动释放,避免因流提前关闭导致加载失败。PDDocument实现了AutoCloseable,可以直接放在try块中。测试PDF文件损坏
换一个确认有效的PDF文件作为测试用例(比如自己生成一个简单的PDF,或用Apache PDFBox官方示例文件),排除文件本身的格式问题。依赖冲突
执行依赖树命令排查是否有旧版PDFBox混入:- Maven:
mvn dependency:tree | grep pdfbox - Gradle:
./gradlew dependencies | grep pdfbox
如果发现1.x版本的依赖,在构建文件中排除:
<!-- Maven排除示例 --> <dependency> <groupId>第三方依赖组</groupId> <artifactId>第三方依赖包</artifactId> <exclusions> <exclusion> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> </exclusion> </exclusions> </dependency>- Maven:
二、完善后的JUnit5测试用例示例
假设你的业务类是PdfToBlobService,包含splitPdfAndUploadToBlob(InputStream pdfStream)方法,以下是用Mockito模拟Blob存储客户端的测试用例:
import org.apache.pdfbox.pdmodel.PDDocument; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class PdfToBlobServiceTest { @Mock private BlobStorageClient blobStorageClient; // 你的Blob存储客户端接口 private final PdfToBlobService service = new PdfToBlobService(blobStorageClient); @Test void splitPdfAndUploadToBlob_ValidPdf_ProcessSuccessfully() throws IOException { // 加载类路径下的有效测试PDF try (InputStream pdfStream = getClass().getResourceAsStream("/valid-test.pdf"); PDDocument document = PDDocument.load(pdfStream)) { assertNotNull(document, "PDF加载失败,检查文件是否存在或损坏"); assertEquals(2, document.getNumberOfPages(), "测试PDF页数不符合预期"); // 重新获取流(因为前面的load已经读取过流,需要重置或重新获取) try (InputStream freshStream = getClass().getResourceAsStream("/valid-test.pdf")) { service.splitPdfAndUploadToBlob(freshStream); // 验证Blob上传调用次数等于PDF页数 verify(blobStorageClient, times(document.getNumberOfPages())) .upload(any(InputStream.class), anyString()); } } } @Test void splitPdfAndUploadToBlob_InvalidPdf_ThrowIOException() { // 用无效字节流模拟损坏的PDF try (InputStream invalidStream = new ByteArrayInputStream("not a pdf content".getBytes())) { assertThrows(IOException.class, () -> service.splitPdfAndUploadToBlob(invalidStream)); } catch (IOException e) { // 忽略流关闭异常 } } @Test void splitPdfAndUploadToBlob_PdfNotFound_ThrowIllegalArgument() { InputStream nonExistentStream = getClass().getResourceAsStream("/non-existent.pdf"); assertThrows(IllegalArgumentException.class, () -> service.splitPdfAndUploadToBlob(nonExistentStream)); } }
三、额外注意事项
- 若业务代码需要将PDF页面转为图片,确保添加
pdfbox-tools依赖(PDFBox 2.0.6需单独引入):
<dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox-tools</artifactId> <version>2.0.6</version> <scope>test</scope> </dependency>
- 测试时不要调用真实的Blob存储服务,用Mock或Testcontainers模拟,保证测试的独立性和执行速度。
内容的提问来源于stack exchange,提问作者madhuri
相关产品推荐
相关产品推荐

