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

Codeception测试Yii2时如何处理预期抛出的UserException

Yii2 Codeception功能测试预期业务异常被误判为错误的解决方法

问题场景

在Yii2框架下编写功能测试用例,校验site/verify-email接口传入空token的场景,测试代码如下:

public function checkEmptyToken2(FunctionalTester $I)
{
    $I->amOnRoute('site/verify-email', ['token' => '']);
    $I->canSee('Email verify token did not come through for some reason');
}

运行测试时,代码抛出了预期内的yii\base\UserException,但Codeception直接将该异常判定为测试错误,执行到请求步骤就终止,没有走到后续的canSee文本校验断言。尝试过用try/catch捕获异常、调用expectException声明预期异常两种方案,都没有解决问题,测试依然报错终止。

报错根因

Codeception的Yii2模块默认会拦截请求处理流程中抛出的所有未捕获异常,直接标记为测试错误,不会把异常交给Yii应用的错误处理器去渲染业务错误页。代码里抛出的UserException没有在控制器层捕获处理,请求流程直接中断,后续的页面断言自然不会执行。

可行解决方案

方案1:修改测试模块配置(推荐,无需改动业务代码)

编辑功能测试套件的配置文件,一般路径为tests/functional.suite.yml,在Yii2模块配置中添加异常过滤规则,让指定的业务异常走应用本身的错误渲染流程,不中断测试:

modules:
  enabled:
    - Yii2:
        configFile: 'config/test.php'
        # 新增以下配置
        errorHandler:
          exceptionFilter:
            class: yii\web\ExceptionFilter
            exceptionMap:
              yii\base\UserException: yii\web\BadRequestHttpException

配置修改完成后,执行命令重新生成测试actor代码:

php vendor/bin/codecept build

配置生效后再运行测试,遇到UserException时不会直接中断,会正常渲染错误提示页,后续的canSee断言可以正常执行校验。

方案2:调整业务代码异常处理逻辑

如果不想修改测试配置,可以在控制器层捕获业务异常,手动渲染错误提示页后返回响应,不要把异常直接抛到应用入口:

// SiteController的actionVerifyEmail方法中调整逻辑
public function actionVerifyEmail($token = '')
{
    try {
        $model = new VerifyEmailForm(['token' => $token]);
        // 原有业务逻辑
    } catch (\yii\base\UserException $e) {
        // 传入错误提示,渲染自定义错误页
        return $this->render('verify-email-fail', ['errorMsg' => $e->getMessage()]);
    }
}

这种场景下请求流程不会抛出未捕获异常,测试会正常加载页面内容,canSee断言可正常工作。

之前方案失效的原因

  • try/catch包裹$I->amOnRoute()无效:异常是在Yii2模块内部的请求分发流程中抛出的,不是在测试方法的当前代码块直接抛出,外层try/catch无法捕获模块内部的异常。
  • expectException无效:该方法是PHPUnit提供的、用于断言测试执行过程中直接抛出指定异常即算测试通过的方法,和需要的「异常抛出后继续校验页面渲染内容」的需求完全不匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 03:12:23