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

PHPUnit 如何实现包含前序异常、自定义属性的异常对象全量比对

目前PHPUnit原生尚未内置支持全量比对异常对象的断言方法,你可以通过自定义封装辅助方法的方式实现你要的简洁调用效果,同时兼顾全量属性比对和自动异常捕获的能力。

方案1:封装测试基类/Trait,调用逻辑和原生expectException对齐

trait FullExceptionAssertTrait
{
    /**
     * 断言会抛出和预期对象完全一致的异常
     * @param \Throwable $expected 预期异常对象
     * @param bool $strict 是否使用引用一致性校验(assertSame)
     */
    public function expectFullException(\Throwable $expected, bool $strict = false): void
    {
        $this->registerCallback(function () use ($expected, $strict) {
            $actual = $this->status->getException();
            if (!$actual) {
                $this->fail('Expected exception was not thrown');
            }
            $strict ? $this->assertSame($expected, $actual) : $this->assertEquals($expected, $actual);
        });
    }
}

调用方式和原生方法完全一致:

public function testControllerThrowsCorrectException()
{
    $previousException = new \RuntimeException('underlying error');
    $expected = new BadRequestException('sample-error-code', $previousException);

    // 仅需一行断言,后续代码抛出的异常会自动比对全量属性
    $this->expectFullException($expected);

    $controller->get();
}

方案2:闭包传入待执行代码,更直观的单行调用

如果不需要和原生调用逻辑对齐,也可以用闭包封装,直接在同一个调用里传入待执行代码:

trait FullExceptionAssertTrait
{
    public function assertThrows(\Throwable $expected, callable $run, bool $strict = false): void
    {
        try {
            $run();
            $this->fail('No exception was thrown');
        } catch (\Throwable $actual) {
            $strict ? $this->assertSame($expected, $actual) : $this->assertEquals($expected, $actual);
        }
    }
}

调用时一行即可完成所有逻辑:

$this->assertThrows(new BadRequestException('sample-error-code', $previousException), fn() => $controller->get());

相关说明

截止到PHPUnit 10稳定版,官方尚未将全量异常比对功能纳入核心开发规划,上述自定义封装方案是目前社区通用的解决方案,不需要额外依赖,同时完全覆盖需求:会自动比对异常的所有属性,包括前序异常、自定义私有属性、异常类、消息、错误码等所有内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:36:04