Laravel测试中如何Mock SFTP磁盘的文件检索操作?
Laravel SFTP存储命令单元测试的Mock方案
问题场景
控制台命令定期从SFTP文件系统拉取文件,需编写单元测试模拟文件系统操作,覆盖文件缺失、内容错误、大小异常等场景。但Laravel官方文档仅支持fake文件上传操作,手动测试无法满足自动化需求。
更新#1:命令中通过
Storage::disk('sftp-disk')->files('path');获取文件,尝试用Storage::shouldReceive('files')->andReturn(['file.xlsx']);进行Mock时,出现以下错误:
Received Mockery_2_Illuminate_Filesystem_FilesystemManager::disk(), but no expectations were specified
正确Mock实现方式
因为Storage::disk()会返回对应磁盘的实例,所以需要先Mockdisk()方法,再Mock该实例上的具体操作方法:
1. 创建并绑定磁盘Mock实例
// 创建SFTP磁盘的契约Mock $sftpDisk = Mockery::mock(\Illuminate\Contracts\Filesystem\Filesystem::class); // 指定Storage调用disk('sftp-disk')时返回这个Mock实例 Storage::shouldReceive('disk') ->with('sftp-disk') ->andReturn($sftpDisk);
2. 模拟不同业务场景
- 模拟存在目标文件
$sftpDisk->shouldReceive('files') ->with('path') ->andReturn(['file.xlsx']);
- 模拟文件缺失场景
$sftpDisk->shouldReceive('files') ->with('path') ->andReturn([]);
- 模拟文件内容错误/大小异常
通过Mockget()或size()方法模拟异常情况:
// 模拟读取到无效内容 $sftpDisk->shouldReceive('get') ->with('path/file.xlsx') ->andReturn('invalid content'); // 模拟文件大小超出限制 $sftpDisk->shouldReceive('size') ->with('path/file.xlsx') ->andReturn(1024 * 1024 * 100); // 100MB
3. 执行命令并验证结果
Mock配置完成后,调用命令并断言预期行为:
$this->artisan('your:command-name') ->assertExitCode(0) ->expectsOutput('文件处理完成');
注意事项
- 确保测试类引入
Mockery及Laravel测试辅助类 - 测试结束后Mock会被Laravel的TestCase自动清理,也可手动调用
Mockery::close()
内容的提问来源于stack exchange,提问作者fudo
相关产品推荐
相关产品推荐

