Send file to Restful service in codeception

2019-06-24 01:54发布

I would like to test restful API test for file uploading.

I try to run:

 $I->sendPOST($this->endpoint, $postData, ['file' => 'example.jpg']);

and I would like it to behave the same as user sent example.jpg file in file input with name file but it doesn't seem to work this way. I'm getting:

[PHPUnit_Framework_ExceptionWrapper] An uploaded file must be an array or an instance of UploadedFile.

Is it possible to upload file using REST plugin in codeception? Documentation is very limited and it's hard to say how to do it.

I'm also testing API using Postman plugin to Google Chrome and I can upload file without a problem using this plugin.

5条回答
冷血范
2楼-- · 2019-06-24 02:21

After testing it seems to make it work we need to use UploadedFile object as file.

For example:

$path = codecept_data_dir();
$filename = 'example-image.jpg';

// copy original test file to have at the same place after test
copy($path . 'example.jpg', $path . $filename);

$mime = 'image/jpeg';

$uploadedFile = new \Symfony\Component\HttpFoundation\File\UploadedFile($path . $filename, $filename, $mime,
    filesize($path . $filename));

$I->sendPOST($this->endpoint, $postData, ['file' => $uploadedFile]);
查看更多
闹够了就滚
3楼-- · 2019-06-24 02:22

['file' => 'example.jpg'] format works too, but the value must be a correct path to existing file.

$path = codecept_data_dir();
$filename = 'example-image.jpg';

// copy original test file to have at the same place after test
copy($path . 'example.jpg', $path . $filename);

$I->sendPOST($this->endpoint, $postData, ['file' =>  $path . $filename]);
查看更多
The star\"
4楼-- · 2019-06-24 02:26

The below worked for myself,

On server:

$uploadedResume= $_FILES['resume_uploader'];
$outPut = [];

        if (isset($uploadedResume) && empty($uploadedResume['error'])) {
            $uploadDirectory = 'uploads/users/' . $userId . '/documents/';
            if (!is_dir($uploadDirectory)) {
                @mkdir($uploadDirectory, 0777, true);
            }

            $ext = explode('.', basename($uploadedResume['name']));
            $targetPath = $uploadDirectory . md5(uniqid()) . '.' . end($ext);

            if (move_uploaded_file($uploadedResume['tmp_name'], $targetPath)) {
                $outPut[] = ['success' => 'success', 'uploaded_path' => $targetPath];
            }
        }
return json_encode($output);

Sorry for the long description code :P

On Testing side:

 //resume.pdf is copied in to tests/_data directory
$I->sendPOST('/student/resume', [], ['resume_uploader' => codecept_data_dir('resume.pdf') ]);
查看更多
孤傲高冷的网名
5楼-- · 2019-06-24 02:31

@Yaronius's answer worked for me after I removed the following header from my test:

$I->haveHttpHeader('Content-Type', 'multipart/form-data');

查看更多
别忘想泡老子
6楼-- · 2019-06-24 02:40

I was struggling with the same problem recently and found out that there is another way to solve the issue without using Symfony's UploadedFile class. You only need to pass the array with file data in the same format as if it were the $_FILES array. For example, this code works perfectly well for me:

$I->sendPOST(
    '/my-awesome-api',
    [
        'sample-field' => 'sample-value',
    ],
    [
        'myFile' => [
            'name' => 'myFile.jpg',
            'type' => 'image/jpeg',
            'error' => UPLOAD_ERR_OK,
            'size' => filesize(codecept_data_dir('myFile.jpg')),
            'tmp_name' => codecept_data_dir('myFile.jpg'),
        ]
    ]
);

Hope this helps someone and prevents from inspecting the framework's source code (which I was forced to do, as the docs skip such an important detail)

查看更多
登录 后发表回答