使用现有测试文件测试Laravel文件上传(PHPUnit)
解决Laravel测试真实Excel文件上传的问题
问题根源
你创建UploadedFile实例时最后一个参数传了false,这个参数控制文件是否被标记为HTTP上传文件,设为false会导致is_uploaded_file()和move_uploaded_file()这类原生函数识别失败——它们只处理真实HTTP请求上传的文件(或Laravel模拟的上传状态)。另外直接用File类实例无法被Laravel的Request解析为上传文件,所以返回null。
正确实现方案
1. 测试代码的正确写法
把测试文件放在项目的tests/Fixtures目录下(没有就新建),可以用两种方式构造合法的上传文件实例:
public function testUploadFile() { // 方法1:用Laravel内置的UploadedFile辅助加载真实文件 $filePath = base_path('tests/Fixtures/test_file.xlsx'); $file = UploadedFile::fake()->create($filePath); // 方法2:手动构造UploadedFile,关键是最后一个参数设为true // $file = new UploadedFile( // $filePath, // 'test_file.xlsx', // 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // null, // true // 标记为HTTP上传文件,让原生函数识别 // ); $response = $this->post('/api/uploadfile', [ 'file' => $file ]); $response->assertOk(); }
2. 控制器代码优化
不要依赖原生的move_uploaded_file(),改用Laravel提供的文件操作方法,兼容测试和生产环境:
public function upload(Request $request) { $file = $request->file('file'); // 先验证文件有效性 if (!$file->isValid()) { return response()->json(['error' => '文件无效'], 400); } // 方法1:用store方法直接存储到Laravel默认存储目录 $path = $file->store('uploads', 'public'); // 方法2:手动指定路径复制文件 // $targetPath = storage_path('app/public/uploads/' . $file->getClientOriginalName()); // \Illuminate\Support\Facades\File::copy($file->getPathname(), $targetPath); // 后续执行Excel内容分析逻辑... }
额外注意事项
- 用
base_path()或storage_path()拼接绝对路径,避免相对路径导致的文件找不到问题。 - 可以在控制器添加请求验证,确保上传的是合法Excel文件:
$request->validate([ 'file' => 'required|file|mimes:xlsx,xls', ]);
内容的提问来源于stack exchange,提问作者Jorge Risquez
相关产品推荐
相关产品推荐

