如何使用表单验证测试 Laravel 媒体上传

How to test Laravel media upload with form validation

前段时间我在 laravel 项目中为我的媒体上传编写了一个测试。测试只是向路由发送带有图像的 post 请求,并检查服务器是否发送 200 状态代码。

use Illuminate\Http\UploadedFile;

/** @test */
public function it_can_upload_image()
{
    $response = $this->post('/media', [
        'media' => new UploadedFile(__DIR__ . "/test_png.png", 'test_png.png'),
    ]);
    $response->assertStatus(200);
}

当我为 media post 参数添加验证规则时,服务器 returns 出现 302 状态代码并且测试失败。但是,当我在浏览器中手动测试媒体上传时,一切正常。

public function uplaodMedia($request) 
{
    $request->validate([
        'media' => 'required'
    ]);

    // ...
}

测试中请求的行为似乎与实际的浏览器请求不同。但是,直到现在我还没有设法解决这个问题。有人 运行 以前做过类似的事情吗?

在为测试创建新的 UploadedFile 时,您需要为 $test 参数传递 true

new UploadedFile(__DIR__ . "/test_png.png", 'test_png.png', null, null, true)

Here 你可以找到构造函数定义:

/**
 * @param bool        $test         Whether the test mode is active
 *                                  Local files are used in test mode hence the code should not enforce HTTP uploads
 */
public function __construct(string $path, string $originalName, string $mimeType = null, int $error = null, bool $test = false)

虽然我不明白为什么要使用真实图像进行此测试,Laravel 提供了一种内置方法来轻松测试文件上传。

来自docs

The Storage facade's fake method allows you to easily generate a fake disk that, combined with the file generation utilities of the UploadedFile class, greatly simplifies the testing of file uploads.

因此您的测试可以简化为以下内容:

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

/** @test */
public function it_can_upload_image()
{        
    Storage::fake();

    $this->post('/media', ['media' => UploadedFile::fake()->image('test_png.png')])
        ->assertStatus(200);
}