【问题标题】:Virtual Filesystem for PHPUnit tests in Laravel 5.4Laravel 5.4 中 PHPUnit 测试的虚拟文件系统
【发布时间】:2017-05-04 22:31:23
【问题描述】:

我的 PHPUnit 集成测试有点问题,我有一个方法可以处理视频文件的表单上传以及该视频的预览图像。

public function store($request)
{
    /** @var Video $resource */
    $resource = new $this->model;

    // Create a new Content before creating the related Photo
    $contentRepo = new ContentRepository();
    $content = $contentRepo->store($request);

    if($content->isValid()) {
        $resource->content_id = $content->id;

        $directory = 'frontend/videos/assets/'.date("Y").'/'.date('m').'/'.time();
        \File::makeDirectory($directory, 0755, true);
        $request->video->move($directory.'/', $request->video->getClientOriginalName());
        $resource->video = '/'.$directory.'/'.$request->video->getClientOriginalName();
        $request->preview_image->move($directory.'/', $request->preview_image->getClientOriginalName());
        $resource->preview_image = '/'.$directory.'/'.$request->preview_image->getClientOriginalName();
        $resource->highlighted = intval($request->input('highlighted') == 'on');

        $resource->save();

        return $resource;
    }
    else {
        return $content;
    }
}

要保留的重要部分是 $request->video->move() 调用,我可能需要替换它才能使用虚拟文件系统。

然后是测试

public function testVideoUpload(){
        File::put(__DIR__.'/frontend/videos/assets/image.mp4', 'test');
        $file = new UploadedFile(__DIR__.'/frontend/videos/assets/image.mp4', 'foofile.mp4', 'video/mp4', 100023, null, $test=true);

        File::put(__DIR__.'/frontend/images/assets/image.jpg', 'test');
        $preview = new UploadedFile(__DIR__.'/frontend/images/assets/image.jpg', 'foofile.jpg', 'image/jpeg', 100023, null, $test=true);

        $this->post('/admin/videos', [
            'title'  => 'My Video #12',
            'description' => 'This is a description',
            'actors' => [$this->actor->id, $this->actor2->id],
            'scenes' => [$this->scene->id, $this->scene2->id],
            'payment_methods' => [$this->paymentMethod->id],
            'video' => $file,
            'preview_image' => $preview
        ])->seeInDatabase('contents', [
            'title'  => 'My Video #12',
            'description' => 'This is a description'
        ]);
}

如您所见,我需要在某个本地目录中创建一个虚拟文件,然后在对表单端点的 HTTP 请求中使用它,然后,该文件将被移动,我需要删除创建的文件夹和新移动的文件......真是一团糟。

因此我想改用虚拟文件系统,但我不知道在这种特殊情况下如何设置它,我已经下载了一个包并设置了它,但问题是,首先,哪个包有您使用/推荐,您将如何调整课程和测试以支持虚拟文件系统?我是否需要切换到使用 Storage 门面而不是 $request->video->move() 调用?如果是这样,那具体怎么做?

提前感谢您的帮助

【问题讨论】:

    标签: phpunit laravel-5.4 virtualfilesystem


    【解决方案1】:

    我无法弄清楚 VFS 系统,但我确实有一些替代方案,它仍然有点混乱,但可以完成工作。

    基本上我在我的 PHPUnit 基类上设置了两个方法来设置和拆除我在任何需要它们的测试中需要的临时文件夹,因为我使用的是数据库事务,文件在每次测试运行时都会被删除,我需要创建每次我运行测试时都有新的虚拟文件。

    所以我有两个方法 setupTempDirectoriesteardownTempDirectories 我将在每个需要这些临时目录的测试的开始和结束时调用它们。

    我将临时文件放在 Storage 目录中,因为有时我通过 PHPStorm 单独运行我的测试,__DIR__ 命令在我这样做时会变得混乱并指向不同的目录,我也尝试了 __FILE__,结果相同,所以我只好使用 Laravel 的 storage_path 来代替,效果很好。

    然后这留下了我的具体类的问题,它试图移动文件并在公共文件夹中为它们创建目录......所以为了解决这个问题,我将代码更改为使用 Storage 门面,然后我模拟我的测试中的存储外观

    所以在我的具体课程中

            $directory = 'frontend/videos/assets/'.date("Y").'/'.date('m').'/'.time();
            Storage::makeDirectory($directory, 0755, true);
    
            Storage::move($request->video, $directory . '/' . $request->video->getClientOriginalName());
            $resource->video = '/'.$directory.'/'.$request->video->getClientOriginalName();
    
            Storage::move($request->preview_image, $directory . '/' . $request->preview_image->getClientOriginalName());
            $resource->preview_image = '/'.$directory.'/'.$request->preview_image->getClientOriginalName();
    

    然后在我的测试中,我模拟了 makeDirectorymove 这样的方法

        // Override the Storage facade with a Mock version so that we don't actually try to move files around...
        Storage::shouldReceive('makeDirectory')->once()->andReturn(true);
        Storage::shouldReceive('move')->twice()->andReturn(true);
    

    这使我的测试工作,并且在完成后实际上并没有留下文件......我希望有人有更好的解决方案,但目前这就是我想出的。 我实际上是在尝试使用 VFS,但它从来没有成功...我不断收到错误消息,即找不到 storage 目录中的原始文件,即使它就在那里...

    我什至不确定 Storage 门面是否在后台使用 VFS,尽管它应该...

    【讨论】:

      猜你喜欢
      • 2017-07-28
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 2016-09-28
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多