ci4.7.2单元测试需用phpunit ^9.6,手动引入ci_testcase.php,用testrequest模拟请求,数据库操作需显式配置sqlite或使用databasetestcase。

CI4.7.2 单元测试跑不起来?先确认 PHPUnit 版本是否兼容
CodeIgniter 4.7.2 默认要求 phpunit ^9.6,不是 ^10.x。用错版本会直接报 Class "PHPUnit\Framework\TestCase" not found 或 Declaration of CI_TestCase::setUp() must be compatible with PHPUnit\Framework\TestCase::setUp(): void。
- 运行
composer show phpunit/phpunit查看当前版本 - 若显示
10.5.x,执行composer require --dev phpunit/phpunit:^9.6降级 - 别删
tests/Bootstrap.php—— CI4 的测试引导逻辑依赖它初始化 vfsStream 和模拟常量 -
phpunit.xml中的bootstrap路径必须是./tests/Bootstrap.php,不能写成相对路径或省略./
写第一个测试类时,为什么 CI_TestCase 找不到?
CI4.7.2 不再自动加载 tests/mocks/ci_testcase.php。这个文件没被 autoload-dev 声明,也不会被 Composer 自动发现。
- 在测试类顶部手动引入:
require_once TESTPATH . 'mocks/ci_testcase.php'; - 继承时用
class HomeTest extends CI_TestCase,不是TestCase -
TESTPATH是框架定义的常量,指向tests/目录,确保它已生效(Bootstrap.php已加载) - 如果仍报错,检查
tests/Bootstrap.php开头是否有defined('TESTPATH') OR define('TESTPATH', __DIR__ . DIRECTORY_SEPARATOR);
测试控制器时,$this->request 总是 null?
CI4.7.2 的测试环境不会自动注入请求对象,CI_TestCase 提供的是模拟器,不是运行时实例。
- 不要在测试里直接访问
$this->request—— 它属于运行时控制器,测试中未初始化 - 要用
$this->request = new TestRequest();或更稳妥地:$this->request = \CodeIgniter\Test\Mock\MockRequest::create(); - 传参给控制器方法前,先调用
$this->request->setGlobal('get', ['id' => 123]); - 若测试中需验证路由行为,记得在
setUp()里调用$this->resetInstance();清空单例状态
数据库测试总失败,get()->getResult() 返回空数组?
CI4.7.2 默认测试不连接真实数据库,ConnectionInterface 在测试中是 mock 实例,除非你显式启用内存数据库或配置 SQLite。
- 不要指望
$this->db->table('users')->get()真去查表 —— 它返回空结果集是正常行为 - 想测查询逻辑,用
$this->db->getCompiledSelect()检查生成的 SQL 是否正确 - 真要跑数据断言,改用
DatabaseTestCase基类,并在setUp()中调用$this->db->query("INSERT INTO users ...")插入测试数据 - SQLite 内存库配置写法:
'DSN' => 'sqlite::memory:', 'DBDebug' => false,放在tests/_support/Database.php里
CI_TestCase 不处理构造函数注入,所有依赖都得手动 mock 或 set 属性,别试图在测试类里写 public function __construct(SomeService $service) —— 容器根本不会解析它。











