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
相关产品推荐
相关产品推荐

