HTTP 客户端 Cakephp 3 忽略 json body

HTTP client Cakephp 3 ignores json body

我目前正在 Cakephp 3 中编写 RESTful API,因此我需要通过 http://host.com/api/pictures 测试 POST 操作。测试代码:

<?php
namespace App\Test\TestCase\Controller;

use App\Controller\Api\UsersController;
use Cake\TestSuite\IntegrationTestCase;
use Cake\Network\Http\Client;
use Cake\Network\Http\FormData;

class ApiPicturesControllerTest extends IntegrationTestCase{
    public $fixtures = [
        'app.users',
        'app.comments',
        'app.albums',
        'app.users_albums'
    ];

    public function testAdd(){
         // $data = new FormData();
         $accessToken ='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjksImV4cCI6MTQ1NzYyOTU3NH0.NnjXWEQCno3PUiwHhnUCBjiknR-NlmT42oPLA5KhuYo';
         $http = new Client([
              'headers' => ['Authorization' => 'Bearer ' . $accessToken, 'Content-Type' => 'application/json']
         ]);
        $data = [
            "album_id" => 1,
            "link" => "http://www.google.com",
            "description" => "testtesttest",
            "favorite" => true
        ];
        $result = $http->post('http://vecto.app/api/pictures/add.json', $data, ['type'=>'json']);

        // $this->assertResponseOk();
        // debug($result);
  }
}

当我尝试调试结果时,我得到一个 'cannot add or update child row',但我确定响应的 ID 确实存在 (固定装置也有 id)。此外,日志指示它仅尝试插入 create/update 行。因此,我很确定数据被忽略了,但是我找不到解决方案。我已经尝试了 headers 的不同组合,例如仅 application/json 用于接受,application/json 用于 Content-Type 等。我正在使用 Cakephp 的 CRUD 插件将数据传递给添加功能。

邮差输出

此外,我尝试了 Postman Chrome 插件来保存数据并且确实有效。有谁知道我在测试中做错了什么?

集成测试用例不是这样使用的。您正在调度一个外部的、真实的请求,它将离开测试环境,而您应该使用集成测试用例提供的请求调度工具,即

  • IntegrationTestCase::get()
  • IntegrationTestCase::post()
  • IntegrationTestCase::put()
  • 等...

这些方法将发送不离开测试环境的模拟请求,这对于正常工作至关重要,因为您想使用测试连接、检查可能的异常、访问已使用的 session等...

也就是说,你应该按照

$accessToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjksImV4cCI6MTQ1NzYyOTU3NH0.NnjXWEQCno3PUiwHhnUCBjiknR-NlmT42oPLA5KhuYo';

$this->configRequest([
    'headers' => [
        'Authorization' => 'Bearer ' . $accessToken,
        'Content-Type' => 'application/json'
    ]
]);

$data = [
    "album_id" => 1,
    "link" => "http://www.google.com",
    "description" => "testtesttest",
    "favorite" => true
];
$this->post('/api/pictures/add.json', json_encode($data));

请注意,application/json 的内容类型将要求您发送原始 JSON 数据!如果您实际上 need/want 不测试原始输入的解析,那么您可以跳过 header,而是将数组作为数据传递。

另见