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

PHPUnit 11与Laravel 11中tearDownAfterClass未触发问题排查

问题:PHPUnit的tearDownAfterClass()方法未被调用

环境版本信息

  • PHPUnit版本:
"phpunit/phpunit": "^11.2"
  • Laravel版本:
"laravel/framework": "^11.10"
  • Composer自动加载配置:
"autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },

测试代码

<?php

namespace Tests\Feature;

use App\Models\Patient;
use App\Models\User;
use Illuminate\Foundation\Testing\TestCase;

class PatientTest extends TestCase
{
    protected $patientData;
    protected $client;
    protected $headers;
    protected $baseEndpoint;

    /**
     * This method is used to set up the test environment before each test
     */
    protected function setUp(): void
    {
        parent::setUp();

        $user = 'dummy';
        $pass = 'dummy';
        $base64Credential = base64_encode("{$user}:{$pass}");

        $this->headers = [
            'Authorization' => "Basic {$base64Credential}",
        ];

        $this->baseEndpoint = 'api/v1/patient';

        $this->patientData = [
            'doc' => '74308804019',
            'name' => 'John Doe',
        ];
    }

    public static function tearDownAfterClass(): void
    {
        parent::tearDownAfterClass();
        $p = Patient::where('email', 'valid@example.com')->delete();
        $u = User::where('email', 'valid@example.com')->delete();

        dump("Patients deleted: " . $p);
        dump("Users deleted: " . $u);
    }

    public function testRouteRequiresAuthentication()
    {
        $response = $this->postJson($this->baseEndpoint, []);

        $response->assertStatus(404);
    }
}

问题描述

执行测试命令 vendor/bin/phpunit tests/Feature/Api/Company/Patient/PatientTest.php --debug 后,debug输出中未显示tearDownAfterClass()被调用的记录,该方法内的清理逻辑未执行。


排查与解决方案

核心原因:PHPUnit 11已废弃tearDownAfterClass方法

PHPUnit 11.x 彻底移除了tearDownAfterClass()这类传统静态生命周期方法,改用属性注解的方式定义类级别的清理逻辑。

修复步骤:改用#[AfterClass]注解

修改测试类中的清理方法,替换为注解形式:

<?php

namespace Tests\Feature;

use App\Models\Patient;
use App\Models\User;
use Illuminate\Foundation\Testing\TestCase;
use PHPUnit\Framework\Attributes\AfterClass; // 必须导入注解类

class PatientTest extends TestCase
{
    // ... 原有属性和setUp方法保持不变 ...

    #[AfterClass]
    public static function cleanUpAfterClass(): void
    {
        $p = Patient::where('email', 'valid@example.com')->delete();
        $u = User::where('email', 'valid@example.com')->delete();

        dump("Patients deleted: " . $p);
        dump("Users deleted: " . $u);

        // 注意:若父类TestCase已移除tearDownAfterClass方法,需删除parent调用
        // parent::tearDownAfterClass();
    }

    // ... 原有测试方法保持不变 ...
}

关键检查点

  1. 必须导入注解类:确保顶部引入PHPUnit\Framework\Attributes\AfterClass,否则注解不会被识别。
  2. 方法修饰符要求:注解标记的方法必须是public static类型,否则无法触发。
  3. 移除废弃方法调用:如果Laravel的TestCase在PHPUnit 11环境下已不再提供tearDownAfterClass(),调用parent::tearDownAfterClass()会引发错误,需删除该行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:53:11