我在 Laravel 测试环境中尝试模拟 multi
Storage
时遇到问题。
这是我的代码:
public function sftp ( Sibling $sibling ) {
$file_paths = Storage::build($sibling->config)
->files($this->track->track_token);
Storage::disk('public')
->makeDirectory($this->track->track_token);
foreach ( $file_paths as $file_path ) {
$file_content = Storage::build($sibling->config)
->get($file_path);
TrackMp3::query()
->where('track_id' , $this->track->id)
->where('file_name' , basename($file_path))
->update([
'downloaded_at' => now() ,
]);
Storage::disk('public')
->put($file_path , $file_content);
}
}
这是我的测试用例:
public function test_sftp_works_when_track_exists_in_sibling () {
$track_token = md5('sample');
$track_320 = UploadedFile::fake()
->create('track_320.mp3')
->getContent();
$track_160 = UploadedFile::fake()
->create('track_160.mp3')
->getContent();
$track_96 = UploadedFile::fake()
->create('track_96.mp3')
->getContent();
$track_demo = UploadedFile::fake()
->create('track_demo.mp3')
->getContent();
$sibling = SiblingFactory::new()
->create();
$public_disk = Storage::fake('public');
$sibling_disk = Storage::fake('sibling');
Storage::shouldReceive('build')
->with($sibling->config)
->andReturn($sibling_disk);
$sibling_disk->put($track_token . '/track_320.mp3' , $track_320);
$sibling_disk->put($track_token . '/track_160.mp3' , $track_160);
$sibling_disk->put($track_token . '/track_96.mp3' , $track_96);
$sibling_disk->put($track_token . '/track_demo.mp3' , $track_demo);
$track = TrackFactory::new()
->md5Fetched()
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_320.mp3')) ])
->fileName320())
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_160.mp3')) ])
->fileName160())
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_96.mp3')) ])
->fileName96())
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_demo.mp3')) ])
->fileNameDemo())
->create([ 'track_token' => $track_token ]);
Storage::fake('public'); // ----> Error happend here
Artisan::call('download');
}
这是错误:
Mockery\Exception\BadMethodCallException: Received Mockery_2_Illuminate_Filesystem_FilesystemManager::createLocalDriver(), but no expectations were specified
C:\Development\projects\track-download-manager\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:353
C:\Development\projects\track-download-manager\vendor\laravel\framework\src\Illuminate\Support\Facades\Storage.php:107
C:\Development\projects\track-download-manager\tests\Feature\DownloadCommandTest.php:55
终于解决了。
我忘了模拟公共磁盘。
public function test_sftp_works_when_track_exists_in_sibling () {
$track_token = md5(rand());
$track_320 = UploadedFile::fake()
->create('track_320.mp3')
->getContent();
$track_160 = UploadedFile::fake()
->create('track_160.mp3')
->getContent();
$track_96 = UploadedFile::fake()
->create('track_96.mp3')
->getContent();
$track_demo = UploadedFile::fake()
->create('track_demo.mp3')
->getContent();
$sibling = SiblingFactory::new()
->create();
$public_disk = Storage::fake('public');
$sibling_disk = Storage::fake('sibling');
Storage::shouldReceive('build')
->with($sibling->config)
->andReturn($sibling_disk);
Storage::shouldReceive('disk')
->with('public')
->andReturn($public_disk);
$sibling_disk->put($track_token . '/track_320.mp3' , $track_320);
$sibling_disk->put($track_token . '/track_160.mp3' , $track_160);
$sibling_disk->put($track_token . '/track_96.mp3' , $track_96);
$sibling_disk->put($track_token . '/track_demo.mp3' , $track_demo);
$track = TrackFactory::new()
->md5Fetched()
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_320.mp3')) ])
->fileName320())
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_160.mp3')) ])
->fileName160())
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_96.mp3')) ])
->fileName96())
->has(TrackMp3Factory::new([ 'md5' => md5_file($sibling_disk->path($track_token . '/track_demo.mp3')) ])
->fileNameDemo())
->create([ 'track_token' => $track_token ]);
Artisan::call('download');
}
您已经多次调用 Storage::fake() 。首先是兄弟姐妹,然后是公众。当您第二次调用它时,Laravel 正在尝试创建本地磁盘,并且因为您之前已经模拟了存储外观,所以测试失败了。
关键是在设置任何模拟之前先设置假货。
$public_disk = Storage::fake('public');
$sibling_disk = Storage::fake('sibling');
Storage::shouldReceive('build')
->with($sibling->config)
->andReturn($sibling_disk);
如果您在此测试中不检查与
Storage::build
的交互,而只需要确保文件正确放置在同级磁盘和公共磁盘上,请考虑删除 shouldReceive('build')
模拟。
如果您仍然遇到问题,可以在完成后重置模拟实例,以确保后续调用不会产生副作用。
Storage::swap($this->app['files']);