You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 10+Livewire 2文件上传组件测试报错:Type is not supported

Laravel 10 + Livewire 2 测试文件上传组件时触发"Type is not supported"错误

问题场景

使用Laravel 10搭配Livewire 2开发文件上传表单组件,编写PHPUnit测试时遇到以下错误,调试确认错误在调用测试中的set()方法时触发,但组件实际运行功能正常。

错误信息

FAILED  Tests\Feature\Livewire\UploadAssetTest > book can be saved correctly                                                             
Type is not supported

  at vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php:88
     84▕             default => json_encode($data, $this->encodingOptions),
     85▕         };
     86▕ 
     87▕         if (! $this->hasValidJson(json_last_error())) {
  ➜  88▕             throw new InvalidArgumentException(json_last_error_msg());
     89▕         }
     90▕ 
     91▕         return $this->update();
     92▕     }

测试代码

/** @test */
public function book_can_be_saved_correctly()
{
    $admin = User::factory()->create();
    $this->actingAs($admin);

    Storage::fake('private');

    $testBook = UploadedFile::fake()->create('private/books/test_book.pdf');
    $testCover = UploadedFile::fake()->image('private/covers/test_image.png');

    $emptyForm = (new UploadBookService())->buildForm();

    $book = array_merge($emptyForm,[            
        'title' => 'Title Test',
        'author' => 'Author Test',
        'description' => 'Description Test',
        'publishedAt' => '2022',
        'cover' => $testCover,
        'book' => $testBook,
    ]);

    $component = Livewire::test(UploadAsset::class)
        ->set('assetMeta', $book)
        ->call('save');

    Storage::assertExists('books/test_book.pdf');
    Storage::assertExists('covers/test_cover.png');
}

问题原因

Livewire测试组件调用set()方法时,会尝试将属性数据序列化为JSON,但UploadedFile实例属于不可JSON序列化的类型,因此触发"Type is not supported"错误。

实际运行场景中,文件通过浏览器的multipart表单请求上传,Livewire会通过专门的文件处理流程接收文件,不会触发JSON序列化逻辑,因此功能正常。

解决办法

1. 使用Livewire测试的attach()方法处理文件上传

Livewire测试工具提供了attach()方法,专门用于模拟浏览器文件上传,避免直接传递UploadedFile实例导致的序列化问题。

2. 拆分数据设置流程

先设置普通文本字段,再通过attach()绑定文件字段,不要将UploadedFile实例混入普通表单数组中传递。

3. 修正Storage断言的磁盘指定

测试中使用Storage::fake('private')模拟了私有磁盘,断言时需要指定该磁盘,否则会默认检查本地磁盘。

修改后的测试代码

/** @test */
public function book_can_be_saved_correctly()
{
    $admin = User::factory()->create();
    $this->actingAs($admin);

    Storage::fake('private');

    // 移除文件路径中的'private/'前缀,fake磁盘根目录已对应private磁盘
    $testBook = UploadedFile::fake()->create('test_book.pdf');
    $testCover = UploadedFile::fake()->image('test_image.png');

    $emptyForm = (new UploadBookService())->buildForm();
    // 仅合并普通文本字段,排除文件实例
    $bookData = array_merge($emptyForm, [
        'title' => 'Title Test',
        'author' => 'Author Test',
        'description' => 'Description Test',
        'publishedAt' => '2022',
    ]);

    $component = Livewire::test(UploadAsset::class)
        ->set('assetMeta', $bookData)
        // 使用attach绑定文件字段,参数为组件属性路径和文件实例
        ->attach('assetMeta.cover', $testCover)
        ->attach('assetMeta.book', $testBook)
        ->call('save');

    // 指定磁盘进行断言
    Storage::disk('private')->assertExists('books/test_book.pdf');
    Storage::disk('private')->assertExists('covers/test_image.png');
}

内容的提问来源于stack exchange,提问作者Marco Silvestri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:25:16