如何在Laravel中模拟Storage文件下载完成功能测试
解决方案
方案1:保持手动Mock的写法,构造磁盘Mock对象
你当前写法的问题在于,disk()方法需要返回一个可继续调用download()方法的磁盘实例Mock,你需要提前构造这个Mock对象再传入andReturn():
public function testClientCanDownloadExport() { // 注意如果用手动Mock就不需要再调用Storage::fake了,二者选其一即可 $export = factory(Export::class)->create(); $file = new File(base_path('tests/_data/ricardo/IntakeDataExport.csv')); // 1. 先构造磁盘实例的Mock,模拟download方法 $diskMock = Mockery::mock(Illuminate\Contracts\Filesystem\Filesystem::class); $diskMock->shouldReceive('download') ->with($export->path) ->andReturn($file); // 2. 让Storage::disk返回你构造的Mock对象 Storage::shouldReceive('disk') ->with('s3-data-exports') ->andReturn($diskMock); $this->json('GET', route('exports.download', $export->id)) ->assertStatus(200); }
注意:手动Mock和Storage::fake不要同时使用,二者功能重叠会导致冲突。
方案2:直接用Storage::fake简化测试(更推荐)
Laravel的Storage假磁盘本身就支持完整的文件操作模拟,不需要手动写Mock逻辑,写法更简洁:
public function testClientCanDownloadExport() { Storage::fake('s3-data-exports'); $export = factory(Export::class)->create(); $testFilePath = base_path('tests/_data/ricardo/IntakeDataExport.csv'); // 把测试文件写入假磁盘对应路径 Storage::disk('s3-data-exports')->put($export->path, file_get_contents($testFilePath)); $this->json('GET', route('exports.download', $export->id)) ->assertStatus(200); }
这种方式会真实模拟S3磁盘的文件读写、下载逻辑,不需要手动处理链式调用的Mock关系,是Laravel官方推荐的Storage相关功能测试方案。
内容的提问来源于stack exchange,提问作者tuscan88
相关产品推荐
相关产品推荐

