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

如何为PDF生成接口搭建PHPUnit功能测试且不修改原有逻辑

PDF下载接口的功能测试方案

问题场景

  • 应用有两个PDF生成入口:/pdf/report 和 /pdf/details
  • 对应调用PDFController的report()和details()方法收集生成PDF所需的数据
  • 两个控制器方法最终都会调用PDFService类的outputPDF($pdf_data)方法,该方法内部通过$pdf->getMpdf()->Output($pdf_data['filename'], 'D')触发浏览器下载

核心痛点

直接修改Output()的输出参数为'S'会改变原有下载逻辑;为测试场景单独给outputPDF()加参数又显得冗余,找不到合理的测试方案


方案1:依赖注入替换Mpdf实例(推荐)

通过依赖注入容器,在测试环境下替换真实的Mpdf实例为Mock对象,拦截Output()调用:

  • 测试时创建Mock版Mpdf类,重写Output()方法,不触发真实下载,而是记录调用参数或返回模拟内容
  • 将Mock实例绑定到容器中,让PDFService使用这个Mock对象而非真实实例
  • 发起接口请求后,验证Mock的Output()是否按预期被调用(检查文件名、输出模式'D'),同时断言响应头是否符合下载要求(比如Content-Disposition包含attachment和对应文件名)

示例代码片段:

// 测试用例中
$mockMpdf = $this->createMock(Mpdf::class);
// 验证Output方法是否以正确参数被调用一次
$mockMpdf->expects($this->once())
    ->method('Output')
    ->with($this->equalTo('report.pdf'), $this->equalTo('D'));

// 替换容器中的Mpdf实例
$this->app->instance(Mpdf::class, $mockMpdf);

// 发起接口请求
$response = $this->get('/pdf/report');

// 验证响应头是否符合下载要求
$this->assertEquals('attachment; filename="report.pdf"', $response->headers->get('Content-Disposition'));

方案2:环境变量控制输出模式

在PDFService::outputPDF()中增加环境判断,测试环境自动切换输出模式为'S',不改变对外方法签名:

// PDFService.php
public function outputPDF($pdf_data) {
    // 测试环境下返回PDF内容,生产环境触发下载
    $outputMode = env('APP_ENV') === 'testing' ? 'S' : 'D';
    return $this->pdf->getMpdf()->Output($pdf_data['filename'], $outputMode);
}
  • 测试时设置APP_ENV=testing,方法会返回PDF内容而非触发下载
  • 发起请求后,可以直接断言返回内容是否为有效PDF(比如检查开头是否是%PDF-),同时验证响应头的正确性

方案3:拦截输出流捕获PDF内容

利用PHP输出控制函数在测试时捕获输出内容,无需修改业务代码:

  • 发起请求前开启输出缓冲
  • 请求结束后获取缓冲内容,同时检查响应头是否符合下载要求
  • 注意:部分框架有自己的输出控制逻辑,可能需要适配框架的测试API

示例代码片段:

// 测试用例中
ob_start();
$response = $this->get('/pdf/report');
$pdfContent = ob_get_clean();

// 验证返回内容是合法PDF
$this->assertStringStartsWith('%PDF-', $pdfContent);
// 验证响应头
$this->assertEquals('attachment; filename="report.pdf"', $response->headers->get('Content-Disposition'));

内容的提问来源于stack exchange,提问作者Cynical

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:45:43