Home >Backend Development >PHP Tutorial >Testing Temporary URLs in Laravel Storage
Laravel provides a powerful and flexible Storage facade for file storage and operations. One feature worth noting is temporaryUrl()
, which can generate temporary URLs for files stored on services like Amazon S3 or DigitalOcean Spaces. However, Laravel's documentation does not cover how to effectively test this method. Testing this can be challenging, especially when using Storage::fake
as the mock storage driver does not support temporaryUrl()
and will throw the following error:
This driver does not support creating temporary URLs.
In this article, we will demonstrate two methods of testing Storage::temporaryUrl()
through a practical example. These methods include emulating a file system and using emulated storage. Both methods ensure your tests remain isolated and reliable.
We will illustrate the testing process using a PriceExport
model, corresponding controllers and test cases. Here are the settings:
<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>
The controller uses the temporaryUrl
method to generate a temporary URL for the file:
<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>
While Storage::fake
does not natively support temporaryUrl
, we can simulate a mock store to emulate the behavior of this method. This approach ensures that you can test without the need for a real storage service.
<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>
This method utilizes Laravel's built-in simulation capabilities to directly simulate the behavior of 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
. Use a simulated version of the simulated store to resolve this issue. Storage::shouldReceive
simplifies the process of mocking methods like temporaryUrl
when testing controllers. By combining these techniques, you can effectively test Storage::temporaryUrl()
and ensure that your application functionality is fully verified.
The above is the detailed content of Testing Temporary URLs in Laravel Storage. For more information, please follow other related articles on the PHP Chinese website!