Yii框架的Request对象怎么模拟_在单元测试中伪造请求【技巧】

冬枫同学_5746

冬枫同学_5746

2026-04-02

399人浏览

原创

yii2单元测试中应使用yii\test\request并用yii::$app->set('request', $mock)注册,而非直接赋值;需显式设置url、method、bodyparams、rawbody、servervars等属性,并手动添加cookie对象,以准确模拟真实请求行为。

yii框架的request对象怎么模拟_在单元测试中伪造请求【技巧】

Yii2 中怎么用 createRequest() 伪造 HTTP 请求对象

单元测试里不能真发 HTTP 请求,得让 Yii::$app->request 返回你可控的实例。Yii2 提供了 yii\test\Request,但它不是开箱即用的“模拟器”,而是个可配置的假请求类,必须手动挂载到应用组件里。

常见错误是直接 new 一个 Request 然后赋值给 Yii::$app->request —— 这会破坏组件生命周期,导致 getIsGet()、getBodyParams() 等方法行为异常,甚至触发 InvalidConfigException。

  • 必须通过 Yii::$app->set('request', $mockRequest) 注册,而不是直接赋值
  • yii\test\Request 的 $url、$method、$bodyParams 等属性需在构造后显式设置,否则默认为空或 null
  • 如果测试中依赖 getRemoteIP() 或 getUserAgent(),记得设置 $serverVars 数组(如 ['REMOTE_ADDR' => '127.0.0.1'])
$request = new \yii\test\Request();
$request->url = '/api/users';
$request->method = 'POST';
$request->bodyParams = ['name' => 'test'];
$request->serverVars = ['REQUEST_METHOD' => 'POST'];
Yii::$app->set('request', $request);

为什么不能用 Mockery 或 PHPUnit::createMock() 直接 mock Request 类

因为 Yii 的 Request 是深度耦合组件:它读取 $_SERVER、$_GET、$_POST,还依赖 Yii::$app->getSecurity() 解密 cookie。纯 mock 会绕过这些逻辑,导致 getCookies() 返回空、getCsrfToken() 报错,或者 resolvePathInfo() 解析失败。

更实际的问题是:很多控制器动作里会调用 $this->request->get() 或 $this->request->post(),而这些方法内部做了参数过滤和类型转换——mock 对象无法复现这一层行为。

Yii Framework 2.0.51
Yii Framework 2.0.51

Yii Framework 2.0.51 官方 Basic 应用模板,适合旧项目兼容、升级验证和开发测试。

下载
  • mock 出的 get() 方法返回的是原始数组,不会自动调用 filterInput()
  • mock 不会响应 enableCsrfValidation = false 配置,CSRF 校验仍可能意外触发
  • 若测试涉及文件上传(getUploadedFiles()),mock 几乎无法还原 $_FILES 结构和临时路径逻辑

yii\test\Request 和真实 yii\web\Request 的关键差异点

它们共享接口,但行为有三处必须注意:

  • getAbsoluteUrl() 在 test\Request 中只拼接 http://localhost + $url,不读 $_SERVER['HTTP_HOST'],所以带端口或 HTTPS 的场景会出错
  • getHostInfo() 默认返回 'http://localhost',无法通过配置覆盖,硬编码写死
  • getCookies() 不解析 $_COOKIE,而是直接返回 $cookies 属性(CookieCollection 实例),需手动 add 一个 Cookie 对象才能生效

如果你的代码里写了 $request->getCookies()->getValue('X-TOKEN'),就得这么配:

$cookie = new \yii\web\Cookie(['name' => 'X-TOKEN', 'value' => 'abc123']);
$request->cookies->add($cookie);

测试 POST JSON 请求时,getRawBody() 和 getJson() 怎么设

Yii 默认不自动解析 JSON body,要靠 getJson() 内部调用 json_decode($this->getRawBody(), true)。所以伪造时不能只设 $bodyParams,还得设 $rawBody 字符串。

  • $bodyParams 是给 get()/post() 用的,不影响 getJson()
  • $rawBody 必须是合法 JSON 字符串,且不能带 BOM 或多余空格,否则 getJson() 返回 null
  • 如果控制器用了 Yii::$app->request->getJson(),但你只设了 bodyParams,结果永远是 null
$request = new \yii\test\Request();
$request->method = 'POST';
$request->rawBody = '{"name":"test","age":25}';
$request->serverVars = ['CONTENT_TYPE' => 'application/json'];

最常被忽略的是 CONTENT_TYPE 没设对,或者 rawBody 是 PHP 数组而非 JSON 字符串——这两个点一错,getJson() 就静默失效,debug 时容易以为是代码问题,其实是测试准备没到位。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

yii yii框架

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2135

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3262

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1096

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

3739

7

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1678

6

cookie
cookie

Cookie 是一种在用户计算机上存储小型文本文件的技术,用于在用户与网站进行交互时收集和存储有关用户的信息。当用户访问一个网站时,网站会将一个包含特定信息的 Cookie 文件发送到用户的浏览器,浏览器会将该 Cookie 存储在用户的计算机上。之后,当用户再次访问该网站时,浏览器会向服务器发送 Cookie,服务器可以根据 Cookie 中的信息来识别用户、跟踪用户行为等。

2023.06.30

11919

10

document.cookie获取不到怎么解决
document.cookie获取不到怎么解决

document.cookie获取不到的解决办法:1、浏览器的隐私设置;2、Same-origin policy;3、HTTPOnly Cookie;4、JavaScript代码错误;5、Cookie不存在或过期等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.11.23

1126

5

阻止所有cookie什么意思
阻止所有cookie什么意思

阻止所有cookie意味着在浏览器中禁止接受和存储网站发送的cookie。阻止所有cookie可能会影响许多网站的使用体验,因为许多网站使用cookie来提供个性化服务、存储用户信息或跟踪用户行为。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

804

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Yii Framework 2.0 API 官方文档
Yii Framework 2.0 API 官方文档

共0课时 | 0人学习

Yii2.0框架开发实战视频教程
Yii2.0框架开发实战视频教程

共22课时 | 9.3万人学习