Codeception seeResponseContainsJson匹配俄文字符数据时报错,如何修复?
修复Codeception中JSON响应字符编码错误导致的断言失败
问题场景
你编写的Codeception测试代码在断言JSON响应内容时失败,错误显示实际响应中的俄文消息出现乱码(XML �� ������ ���������),与预期的XML не прошел валидацию不匹配,使用的Codeception版本为4.2.2。
测试代码如下:
$I->wantTo("Create new claim"); $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json; charset=utf-8'); $I->amBearerAuthenticated($I->generateCorrectToken($example['userId'])); $I->sendPostAsJson('/api/claims/', $example['json']); $I->seeResponseCodeIsSuccessful(); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType([ 'code' => 'integer', 'message' => 'string', 'status' => 'boolean', ]); $I->seeResponseContainsJson([ 'code' => 2058, 'status' => false, 'message' => 'XML не прошел валидацию', ]);
错误信息:
Fail Response JSON does not contain the provided JSON
- Expected | + Actual @@ @@ Array ( 'code' => 2058 'status' => false
- 'message' => 'XML �� ������ ���������'
- 'message' => 'XML не прошел валидацию' )
问题原因
核心是字符编码不匹配:
- 后端接口返回的JSON响应未正确使用UTF-8编码传输
- Codeception解析响应时未采用正确的编码格式
- 测试文件本身的编码非UTF-8,导致预期字符串编码错误
解决方案
1. 修复后端接口的响应编码(根本解决)
确保后端接口在返回JSON时,响应头明确设置Content-Type: application/json; charset=utf-8,保证响应内容以UTF-8编码输出。
2. 在测试中强制指定接受编码
在请求头中添加Accept-Charset,告诉服务器返回UTF-8编码的内容:
// 在发送请求前添加这行 $I->haveHttpHeader('Accept-Charset', 'utf-8');
3. 手动设置Codeception的响应编码
如果服务器响应头正确,但Codeception仍解析错误,可以在请求后强制设置响应编码:
$I->sendPostAsJson('/api/claims/', $example['json']); // 添加以下两行 $I->grabResponse(); // 触发响应解析 $I->setResponseEncoding('UTF-8');
4. 改用字符串匹配作为临时替代
如果上述方案暂时无法生效,可以替换seeResponseContainsJson为seeResponseContains,直接匹配响应字符串:
// 替换原有的seeResponseContainsJson断言 $I->seeResponseContains('"message": "XML не прошел валидацию"');
5. 检查测试文件编码
确保你的测试PHP文件是以UTF-8无BOM格式保存的,避免预期字符串本身编码错误。
修改后的测试代码示例
$I->wantTo("Create new claim"); $I->haveHttpHeader('accept', 'application/json'); $I->haveHttpHeader('content-type', 'application/json; charset=utf-8'); $I->haveHttpHeader('Accept-Charset', 'utf-8'); // 新增:指定接受编码 $I->amBearerAuthenticated($I->generateCorrectToken($example['userId'])); $I->sendPostAsJson('/api/claims/', $example['json']); $I->grabResponse(); $I->setResponseEncoding('UTF-8'); // 新增:强制设置响应编码 $I->seeResponseCodeIsSuccessful(); $I->seeResponseIsJson(); $I->seeResponseMatchesJsonType([ 'code' => 'integer', 'message' => 'string', 'status' => 'boolean', ]); $I->seeResponseContainsJson([ 'code' => 2058, 'status' => false, 'message' => 'XML не прошел валидацию', ]);
内容的提问来源于stack exchange,提问作者Dmitriy
相关产品推荐
相关产品推荐

