如何在 Laravel 5.2 中测试文件上传

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36408134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 13:31:42  来源:igfitidea点击:

How to test file upload in Laravel 5.2

phpunit-testinglaraveltestingupload

提问by Ramin

Im trying to test an upload API but it fails every time:

我正在尝试测试上传 API,但每次都失败:

Test Code :

测试代码:

$JSONResponse = $this->call('POST', '/upload', [], [], [
    'photo' => new UploadedFile(base_path('public/uploads/test') . '/34610974.jpg', '34610974.jpg')
]);

$this->assertResponseOk();
$this->seeJsonStructure(['name']);

$response = json_decode($JSONResponse);
$this->assertTrue(file_exists(base_path('public/uploads') . '/' . $response['name']));

file path is /public/uploads/test/34610974.jpg

文件路径是/public/uploads/test/34610974.jpg

Here is My Upload code in a controller :

这是我在控制器中的上传代码:

$this->validate($request, [
    'photo' => 'bail|required|image|max:1024'
]);

$name = 'adummyname' . '.' . $request->file('photo')->getClientOriginalExtension();

$request->file('photo')->move('/uploads', $name);

return response()->json(['name' => $name]);

How should I test file upload in Laravel 5.2? How to use callmethod to upload a file?

我应该如何在Laravel 5.2 中测试文件上传?如何使用call方法上传文件?

回答by peterm

When you create an instance of UploadedFileset the last parameter $testto true.

创建实例时,UploadedFile将最后一个参数设置$testtrue.

$file = new UploadedFile($path, $name, filesize($path), 'image/png', null, true);
                                                                           ^^^^

Here is a quick example of a working test. It expects that you have a stub test.pngfile in tests/stubsfolder.

这是一个工作测试的快速示例。它期望您test.pngtests/stubs文件夹中有一个存根文件。

class UploadTest extends TestCase
{
    public function test_upload_works()
    {
        $stub = __DIR__.'/stubs/test.png';
        $name = str_random(8).'.png';
        $path = sys_get_temp_dir().'/'.$name;

        copy($stub, $path);

        $file = new UploadedFile($path, $name, filesize($path), 'image/png', null, true);
        $response = $this->call('POST', '/upload', [], [], ['photo' => $file], ['Accept' => 'application/json']);

        $this->assertResponseOk();
        $content = json_decode($response->getContent());
        $this->assertObjectHasAttribute('name', $content);

        $uploaded = 'uploads'.DIRECTORY_SEPARATOR.$content->name;
        $this->assertFileExists(public_path($uploaded));

        @unlink($uploaded);
    }
}
? phpunit tests/UploadTest.php
PHPUnit 4.8.24 by Sebastian Bergmann and contributors.

.

Time: 2.97 seconds, Memory: 14.00Mb

OK (1 test, 3 assertions)

回答by MiCc83

In Laravel 5.4 you can also use \Illuminate\Http\UploadedFile::fake(). A simple example below:

在 Laravel 5.4 中,您还可以使用\Illuminate\Http\UploadedFile::fake(). 下面是一个简单的例子:

/**
 * @test
 */
public function it_should_allow_to_upload_an_image_attachment()
{
    $this->post(
        action('AttachmentController@store'),
        ['file' => UploadedFile::fake()->image('file.png', 600, 600)]
    );

    /** @var \App\Attachment $attachment */
    $this->assertNotNull($attachment = Attachment::query()->first());
    $this->assertFileExists($attachment->path());
    @unlink($attachment->path());
}

If you want to fake a different file type you can use

如果你想伪造不同的文件类型,你可以使用

UploadedFile::fake()->create($name, $kilobytes = 0)

More information directly on Laravel Documentation.

更多信息直接在Laravel 文档中

回答by joel kithinji

The laravel documentation has an answer for when you want to test a fake file. When you want to test using a real file in laravel 6 you can do the following:

laravel 文档有关于何时测试假文件的答案。当您想在 laravel 6 中使用真实文件进行测试时,您可以执行以下操作:

namespace Tests\Feature;

use Illuminate\Http\UploadedFile;
use Tests\TestCase;

class UploadsTest extends TestCase
{
    // This authenticates a user, useful for authenticated routes
    public function setUp(): void
    {
        parent::setUp();
        $user = User::first();
        $this->actingAs($user);
    }    

    public function testUploadFile()
    {
        $name = 'file.xlsx';
        $path = 'absolute_directory_of_file/' . $name;
        $file = new UploadedFile($path, $name, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', null, true);
        $route = 'route_for_upload';
        // Params contains any post parameters
        $params = [];
        $response = $this->call('POST', $route, $params, [], ['upload' => $file]);
        $response->assertStatus(200);
    }  

}

回答by Mahmoud Zalt

You can find this code at this link

您可以在此链接中找到此代码

Setup

设置

/**
 * @param      $fileName
 * @param      $stubDirPath
 * @param null $mimeType
 * @param null $size
 *
 * @return  \Illuminate\Http\UploadedFile
 */
public static function getTestingFile($fileName, $stubDirPath, $mimeType = null, $size = null)
{
    $file =  $stubDirPath . $fileName;

    return new \Illuminate\Http\UploadedFile\UploadedFile($file, $fileName, $mimeType, $size, $error = null, $testMode = true);
}

Usage

用法

    $fileName = 'orders.csv';
    $filePath = __DIR__ . '/Stubs/';

    $file = $this->getTestingFile($fileName, $filePath, 'text/csv', 2100);

Folder Structure:

文件夹结构:

- MyTests
  - TestA.php
  - Stubs
    - orders.csv