存储中的模拟文件以在Laravel中下载

时间:2018-12-25 19:26:13

标签: php laravel laravel-5.6

是否可以使用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);
}

4 个答案:

答案 0 :(得分:1)

我可能在这里迟到了。但希望帮助其他访问此问题的人给出实现该问题的想法。

这里是带有一些断言的示例。

<?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');
    }
}

答案 1 :(得分:0)

您可以直接直接创建一个新文件,也可以复制特定的测试文件,例如:

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。您可以详细了解in the official documentation

答案 2 :(得分:0)

您可以用来解决该问题的是灯具。 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的此功能,有一些相当不错的文档on here

关于将文件放置在此处,一旦setUp正常工作,就没有什么可以阻止您将文件扔在上面。

答案 3 :(得分:0)

是的,你可以使用 Laravel 的假文件存储功能(mocking):

use Illuminate\Http\UploadedFile;

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

如果您想创建具有特定内容的文本/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

中找到此方法定义