You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
    

二、完善后的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:02:59