如何使用laravel和phpunit测试文件上传?

2022-08-30 17:07:09

我正在尝试在我的laravel控制器上运行此功能测试。我想测试图像处理,但要这样做,我想伪造图像上传。我该怎么做?我在网上找到了一些例子,但似乎没有一个适合我。以下是我所拥有的:

public function testResizeMethod()
{
    $this->prepareCleanDB();

    $this->_createAccessableCompany();

    $local_file = __DIR__ . '/test-files/large-avatar.jpg';

    $uploadedFile = new Symfony\Component\HttpFoundation\File\UploadedFile(
        $local_file,
        'large-avatar.jpg',
        'image/jpeg',
        null,
        null,
        true
    );


    $values =  array(
        'company_id' => $this->company->id
    );

    $response = $this->action(
        'POST',
        'FileStorageController@store',
        $values,
        ['file' => $uploadedFile]
    );

    $readable_response = $this->getReadableResponseObject($response);
}

但控制器不会通过此检查:

elseif (!Input::hasFile('file'))
{
    return Response::error('No file uploaded');
}

因此,不知何故,文件未正确传递。我该怎么做?


答案 1

对于偶然发现此问题的其他人,您现在可以这样做:

    $response = $this->postJson('/product-import', [
        'file' => new \Illuminate\Http\UploadedFile(resource_path('test-files/large-avatar.jpg'), 'large-avatar.jpg', null, null, null, true),
    ]);

更新

Laravel 6 中,Class 的构造函数有 5 个参数,而不是 6 个参数。这是新的构造函数:\Illuminate\Http\UploadedFile

    /**
     * @param string      $path         The full temporary path to the file
     * @param string      $originalName The original file name of the uploaded file
     * @param string|null $mimeType     The type of the file as provided by PHP; null defaults to application/octet-stream
     * @param int|null    $error        The error constant of the upload (one of PHP's UPLOAD_ERR_XXX constants); null defaults to UPLOAD_ERR_OK
     * @param bool        $test         Whether the test mode is active
     *                                  Local files are used in test mode hence the code should not enforce HTTP uploads
     *
     * @throws FileException         If file_uploads is disabled
     * @throws FileNotFoundException If the file does not exist
     */
    public function __construct(string $path, string $originalName, string $mimeType = null, int $error = null, $test = false)
    {
        // ...
    }

因此,上述解决方案变得简单:

$response = $this->postJson('/product-import', [
        'file' => new \Illuminate\Http\UploadedFile(resource_path('test-files/large-avatar.jpg'), 'large-avatar.jpg', null, null, true),
    ]);

它对我有用。


答案 2

Docs for CrawlerTrait.html#method_action内容如下:

参数
字符串 $method
字符串 $action
数组 $wildcards
数组 $parameters
数组 $cookies
数组 $files
数组 $server
字符串 $content

所以我假设正确的调用应该是

$response = $this->action(
    'POST',
    'FileStorageController@store',
    [],
    $values,
    [],
    ['file' => $uploadedFile]
);

除非它需要非空通配符和 Cookie。


推荐