4

Laravel 7 には、ファイルを S3 ディスクに保存し、一時的な URL を返すルートがあります。コードを簡略化すると、次のようになります。

Storage::disk('s3')->put('image.jpg', $file);
return Storage::disk('s3')->temporaryUrl('image.jpg');

そのルートのテストを書きたいと思います。これは通常、Laravel では簡単です。でストレージをモックしStorage::fake('s3')、でファイルの作成をアサートしますStorage::disk('s3')->assertExists('image.jpg')

フェイクストレージは対応しておりませんStorage::temporaryUrl()。そのメソッドを使用しようとすると、次のエラーがスローされます。

このドライバーは、一時 URL の作成をサポートしていません。

一般的な回避策は、Laravel の低レベルのモック API を次のように使用することです。

Storage::shouldReceive('temporaryUrl')
  ->once()
  ->andReturn('http://examples.com/a-temporary-url');

この解決策は、LaraCasts スレッドGitHub の問題で推奨されており、Storage::fake().

その 2 つのアプローチを組み合わせて、両方を行うルートをテストする方法はありますか?

再実装は避けたいStorage::fake()Storage::temporaryUrl()また、環境がテスト中の場合は呼び出さないというチェックを本番コードに追加することは避けたいと思います。後者は、前述の LaraCasts スレッドで提案されている別の回避策です。

4

3 に答える 3

3

私は同じ問題を抱えていて、次の解決策を思いつきました:

$fakeFilesystem = Storage::fake('somediskname');
$proxyMockedFakeFilesystem = Mockery::mock($fakeFilesystem);
$proxyMockedFakeFilesystem->shouldReceive('temporaryUrl')
    ->andReturn('http://some-signed-url.test');
Storage::set('somediskname', $proxyMockedFakeFilesystem);

Storage::disk('somediskname')->temporaryUrl('somefile.png', now()->addMinutes(20))戻ってきて、それ以上の変更なしhttp://some-signed-url.testで提供する一時ファイルシステムに実際にファイルを保存できます。Storage::fake()

于 2021-04-02T22:52:15.710 に答える