Laravel 提供了一個強大且靈活的 Storage facade 用於檔案儲存和操作。一個值得注意的功能是 temporaryUrl()
,它可以為儲存在 Amazon S3 或 DigitalOcean Spaces 等服務上的檔案產生臨時 URL。但是,Laravel 的文檔沒有涵蓋如何有效地測試此方法。測試它可能會帶來挑戰,尤其是在使用 Storage::fake
時,因為模擬儲存驅動程式不支援 temporaryUrl()
並會拋出以下錯誤:
此驅動程式不支援建立臨時 URL。
在本文中,我們將透過一個實際範例來示範兩種測試 Storage::temporaryUrl()
的方法。這些方法包括模擬檔案系統和使用模擬儲存。兩種方法都能確保您的測試保持隔離和可靠。
我們將使用 PriceExport
模型、對應的控制器和測試案例來說明測試過程。以下是設定:
<code class="language-php">final class PriceExport extends Model { protected $fillable = [ 'user_id', 'supplier_id', 'path', 'is_auto', 'is_ready', 'is_send', ]; public function user(): BelongsTo { return $this->belongsTo(User::class); } public function supplier(): BelongsTo { return $this->belongsTo(Supplier::class); } }</code>
控制器使用 temporaryUrl
方法產生檔案的臨時 URL:
<code class="language-php">final class PriceExportController extends Controller { /** * @throws ItemNotFoundException */ public function download(PriceExport $priceExport): DownloadFileResource { if (!$priceExport->is_ready || empty($priceExport->path)) { throw new ItemNotFoundException('price export'); } $fileName = basename($priceExport->path); $diskS3 = Storage::disk(StorageDiskName::DO_S3->value); $url = $diskS3->temporaryUrl($priceExport->path, Carbon::now()->addHour()); $downloadFileDTO = new DownloadFileDTO($url, $fileName); return DownloadFileResource::make($downloadFileDTO); } }</code>
雖然 Storage::fake
本身不支援 temporaryUrl
,但我們可以模擬模擬儲存來模擬該方法的行為。這種方法可確保您可以在無需真實儲存服務的情況下進行測試。
<code class="language-php">final class PriceExportTest extends TestCase { public function test_price_export_download_fake(): void { // 安排 $user = $this->getDefaultUser(); $this->actingAsFrontendUser($user); $supplier = SupplierFactory::new()->create(); $priceExport = PriceExportFactory::new()->for($user)->for($supplier)->create([ 'path' => 'price-export/price-2025.xlsx', ]); $expectedUrl = 'https://temporary-url.com/supplier-price-export-2025.xlsx'; $expectedFileName = basename($priceExport->path); $fakeFilesystem = Storage::fake(StorageDiskName::DO_S3->value); // 模拟模拟文件系统 $proxyMockedFakeFilesystem = Mockery::mock($fakeFilesystem); $proxyMockedFakeFilesystem->shouldReceive('temporaryUrl')->andReturn($expectedUrl); Storage::set(StorageDiskName::DO_S3->value, $proxyMockedFakeFilesystem); // 操作 $response = $this->postJson(route('api-v2:price-export.price-exports.download', $priceExport)); // 断言 $response->assertOk()->assertJson([ 'data' => [ 'name' => $expectedFileName, 'url' => $expectedUrl, ] ]); } }</code>
此方法利用 Laravel 內建的模擬功能來直接模擬 temporaryUrl
的行為。
<code class="language-php">final class PriceExportTest extends TestCase { public function test_price_export_download_mock(): void { // 安排 $user = $this->getDefaultUser(); $this->actingAsFrontendUser($user); $supplier = SupplierFactory::new()->create(); $priceExport = PriceExportFactory::new()->for($user)->for($supplier)->create([ 'path' => 'price-export/price-2025.xlsx', ]); $expectedUrl = 'https://temporary-url.com/supplier-price-export-2025.xlsx'; $expectedFileName = basename($priceExport->path); // 模拟存储行为 Storage::shouldReceive('disk')->with(StorageDiskName::DO_S3->value)->andReturnSelf(); Storage::shouldReceive('temporaryUrl')->andReturn($expectedUrl); // 操作 $response = $this->postJson(route('api-v2:price-export.price-exports.download', $priceExport)); // 断言 $response->assertOk()->assertJson([ 'data' => [ 'name' => $expectedFileName, 'url' => $expectedUrl, ] ]); } }</code>
temporaryUrl
。使用模擬儲存的模擬版本來解決此問題。 Storage::shouldReceive
簡化了在測試控制器時模擬 temporaryUrl
等方法的過程。 透過結合這些技術,您可以有效地測試 Storage::temporaryUrl()
並確保您的應用程式功能得到充分驗證。
以上是測試 Laravel 儲存中的暫存 URL的詳細內容。更多資訊請關注PHP中文網其他相關文章!