createapplication() 必须调用并返回think\app实例,否则所有请求方法报错;tests/目录须与app/同级且命名规范,mock需传完整命名空间路径。

createApplication() 必须调用,否则所有请求方法($this->get()、$this->post())直接报错。
ThinkPHP6 的单元测试不是“装完 PHPUnit 就能跑”,核心卡点在于框架实例没初始化。你写了个 UserLogicTest,但 $this->mock('app\common\logic\UserLogic') 报 Class not found,或者 $this->get('/user') 拿到空响应甚至 Call to a member function bind() on null —— 这些都不是测试写错了,是 createApplication() 没执行,或执行路径不对。
tests/ 目录必须和 app/ 同级,不能塞进 app/ 里
PHPUnit 默认从当前工作目录找 phpunit.xml 和 tests/;如果把 tests/ 放在 app/tests/ 下,它根本不会扫描,也不会加载 bootstrap="vendor/autoload.php"。
-
project-root/是你的项目根目录(含composer.json) -
project-root/app/是应用目录 -
project-root/tests/是唯一被识别的测试根目录(可再建tests/unit/、tests/feature/子目录) - 别在
tests/里放bootstrap.php—— ThinkPHP 的基类已接管自动加载和初始化
TestCase.php 中 createApplication() 必须返回 think\App 实例
这个方法不是可选的,是所有 TP6 测试功能的启动开关。返回值类型错了,$this->mock()、$this->get() 全部失效。
- 正确写法:
return include __DIR__ . '/../thinkphp/start.php'; - 错误写法:
include __DIR__ . '/../public/index.php'—— 这会触发 HTTP 响应输出,导致测试中断 - 不要返回
think\Container或think\Facade,必须是think\App实例 - TP6.1+ 可用
think\facade\App::getFacadeRoot(),但前提是createApplication()已成功执行并完成初始化
测试文件名和类名必须严格匹配 + Test.php 结尾
PHPUnit 只认 *Test.php 文件,且只加载其中与文件名完全一致的类。名字差一个字母、大小写不一致、后缀写成 .php 而非 Test.php,都会被跳过。
- ✅ 正确:
tests/unit/logic/UserLogicTest.php→class UserLogicTest extends TestCase - ❌ 错误:
UserTest.php里定义class UserLogicTest→ 不识别 - ❌ 错误:
UserLogic.php→ 后缀不对,直接忽略 - 命名空间建议对齐被测代码路径,比如
app\common\logic\UserLogic对应tests\unit\common\logic\UserLogicTest
$this->mock() 只支持完整命名空间路径
ThinkPHP 自带的 mock() 不做类名解析,不走自动加载补全,传进去什么就按什么去反射 —— 所以路径错一点就炸。
- ✅ 正确:
$this->mock('app\common\service\UserService') - ❌ 错误:
$this->mock('UserService')→Class not found - ❌ 错误:
$this->mock('common\service\UserService')→ 缺少app\根命名空间 - mock 的目标类必须真实存在,且不能是 final 类(否则需用
getMockForAbstractClass等替代方案)
createApplication() 后的容器状态取决于 start.php 加载的配置和事件。如果你 mock 了一个服务,但它的依赖项(比如数据库连接)没被初始化,后续调用仍可能失败 —— 这时候得看 config/app.php 是否启用了调试模式,以及 think\App 初始化时是否加载了对应 provider。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











