Laravel文件上传测试断言失败:Unable to find a file at path 解决方法
Laravel测试文件上传断言失败:Unable to find a file at path
我来帮你搞定这个问题,核心问题出在磁盘名称的写法和文件存储路径的断言逻辑上,咱们一步步修正:
问题根源分析
- 你在测试和控制器里都错误地用了
/public作为磁盘名称,但Laravel的磁盘配置里(config/filesystems.php),公共磁盘的名称是public,不需要加斜杠。 - 控制器里调用
store('file', 'public')时,文件会被存在public磁盘的file子目录下,但你的测试里直接断言根目录下存在该文件,路径不匹配。 - 另外你的控制器代码还有几个变量未定义的问题(比如
$user、$assortment),这也会导致实际存储失败,进而测试断言出错。
修正步骤
1. 修正测试代码
把磁盘名称改为public,并且断言时要加上存储的子目录前缀file/:
public function testUserCanUploadFile() { $this->withoutExceptionHandling(); $this->signIn(); Storage::fake('public'); // 去掉斜杠,用正确的磁盘名称 $file = UploadedFile::fake()->image('test.jpg'); $assortmentAttributes = Assortment::factory()->raw(); $assortmentAttributes['image'] = $file; $this->post(route('assortments.store'), $assortmentAttributes)->assertRedirect(); // 断言时加上存储的子目录,并且用hashName()获取实际存储的文件名 Storage::disk('public')->assertExists('file/' . $file->hashName()); }
2. 修正控制器代码
首先修正磁盘名称,然后补全未定义的变量(比如通过auth()获取当前用户,从请求中获取分类ID等):
public function store(Request $request) { // 先验证请求数据(建议加上,保证数据合法性) $validated = $request->validate([ 'image' => 'required|image', 'category_id' => 'required|exists:categories,id', 'title' => 'required|string', 'description' => 'nullable|string', ]); // 存储文件并创建Assortment记录 $filePath = $request->file('image')->store('file', 'public'); // 磁盘名称改为public $assortment = Assortment::create([ 'file' => $filePath, 'user_id' => auth()->id(), // 通过auth()获取当前登录用户ID 'category_id' => $validated['category_id'], 'title' => $validated['title'], 'description' => $validated['description'] ?? '' ]); if ($request->wantsJson()) { return response([], 204); } return redirect()->route('assortments.show', $assortment->slug) ->with('success','Verzameling is succesvol aangemaakt.'); }
为什么之前用$file->hashName()还失败?
因为你没加上存储时指定的file子目录,Laravel的store方法会把文件放到你指定的第一个参数目录下,所以实际文件路径是file/[hashName].jpg,而不是根目录下的[hashName].jpg。
这样修正后,测试就能正确断言文件是否存在了,同时控制器的逻辑也能正常运行。
内容的提问来源于stack exchange,提问作者Parsa Gholamhossein
相关产品推荐
相关产品推荐

