簡體   English   中英

存儲中的模擬文件以在 Laravel 中下載

[英]Mock file in Storage to download in Laravel

有沒有辦法使用 Laravels Storage::fake()方法模擬文件?

我已經使用https://laravel.com/docs/5.7/mocking#storage-fake作為我測試的基礎,它適用於上傳。 但是我的下載測試很難看,因為我每次都必須先使用模擬上傳UploadedFile::fake()->image('avatar.jpg')運行我的上傳路線。 有沒有辦法跳過那部分並模擬文件直接存在於假存儲系統中?

public function testAvatarUpload()
{
    Storage::fake('avatars');

    // This is the call I would like to change into a mocked existing uploaded file
    $uploadResponse = $this->json('POST', '/avatar', [
        'avatar' => UploadedFile::fake()->image('avatar.jpg')
    ]);

    // Download the first avatar
    $response = $this->get('/download/avatar/1');

    $response->assertStatus(200);
}

我可能來晚了。 但想幫助訪問此問題的其他人提供實施它的想法。

這是一個帶有一些斷言的示例。

<?php

namespace Tests\Feature\Upload;

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class SampleDownloadTest extends TestCase
{
    /**
     * @test
     */
    public function uploaded_file_downloads_correctly()
    {
        //keep a sample file inside projectroot/resources/files folder
        //create a file from it
        $exampleFile = new File(resource_path('files/test-file.png'))
        //copy that file to projectroot/storage/app/uploads folder
        Storage::putFileAs('/uploads', $exampleFile, 'test-file.png');

        //make request to file download url to get file 
        $response = $this->get("/files/file/download/url");

        //check whethe response was ok
        $response->assertOk();
        $response->assertHeader('Content-Type', 'image/png')
        //check whether file exists in path
        Storage::assertExists('/uploads/test-file.png');
        //do some more assertions.....
        //after test delete the file from storage path
        Storage::delete('uploads/test-file.png');
        //check whether file was deleted
        Storage::assertMissing('/uploads/test-file.png');
    }
}

您可以直接創建一個新文件或復制一個特定的測試文件,例如:

use Illuminate\Http\File;
use Illuminate\Support\Facades\Storage;

// for simple text files or if the content doesn't matter
Storage::disk('avatars')->put('avatar.jpg', 'some non-jpg content');

// if you need a specific file for your test
$file = new File(base_path('tests/resources/avatar.jpg'));
Storage::disk('avatars')->putFileAs('/', $file, 'avatar.jpg');

后者的功能將在$file和給定的名義復制avatar.jpg到指定目錄/磁盤上的avatars 您可以在官方文檔中閱讀更多相關信息。

你可以用來解決這個問題的是夾具。 Laravel 的測試框架本質上是 PHPUnit,所以我看不出它行不通的原因。

像這樣定義你的測試:

use Tests\TestCase;

class ExampleTest extends TestCase {
    protected function setUp() {
        parent::setUp();
        Storage::fake('avatars');
        $uploadResponse = $this->json('POST', '/avatar', [
          'avatar' => UploadedFile::fake()->image('avatar.jpg')
        ]);
    }
    protected function tearDown() {
        parent::tearDown();
    }
    public function testAvatarUpload() {
        // Download the first avatar
        $response = $this->get('/download/avatar/1');

        $response->assertStatus(200);
    }
}

setUptearDown分別在類中的每個測試之前和之后被調用。 因此,在每個測試方法之前, setUp將擦除avatars假磁盤並運行請求。 由於測試后無事可做(因為Storage::fake()替換已經存在的磁盤),該方法為空; 我把它留在這里純粹是為了使示例完整。

關於 PHPunit 的這個特性, 這里有一些非常好的文檔。

關於把在那里的文件,一旦你有你setUp正常工作,並沒有什么東西扔上的文件阻止你。

是的,您可以使用 Laravel 的假文件存儲功能(模擬):

use Illuminate\Http\UploadedFile;

$file = UploadedFile::fake()->create('filename.ext', $sizeInKb)->store('filename.ext');

如果要創建具有特定內容的 text/csv 文件,可以使用以下命令:

use Illuminate\Http\UploadedFile;

$header = 'a,b,c';
$row1 = 'x,y,z';
$row2 = 's,f,t';
$row3 = 'r,i,o';

$content = implode("\n", [$header, $row1, $row2, $row3]);

$file = UploadedFile::fake()->createWithContent('filename.ext', $content)->store('filename.ext');


你可以在Illuminate\\Http\\Testing\\FileFactory找到這些方法的定義

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM