2017-05-04 123 views
1

我对PHPUnit集成测试有点问题,我有一个方法可以处理视频文件的表单上传以及该视频的预览图像。Laravel 5.4 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请求到窗体的终点,那么在此之后,该文件将被移动,我需要删除创建的文件夹和新移动的文件...这是一个真正的混乱。因为我想使用虚拟文件系统,但我不知道如何设置它在这种特殊情况下,我已经下载了一个包并设置它,但问题是,首先,哪些包你有没有使用/推荐,以及如何调整课程和测试以支持虚拟文件系统?我需要切换到使用存储门面而不是$request->video->move()呼叫吗?如果是的话,那究竟会如何呢?

预先感谢您的帮助

回答

1

我无法弄清楚的VFS系统,然而,我有这仍然有点混乱,但能够完成任务的替代有点的。

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

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

我把我的临时文件的存储目录,因为有时我通过PHPStorm单独运行我的测试和__DIR__命令得到弄糟,并且指向不同的目录,当我这样做,我也尝试__FILE__具有相同的结果,所以我只是诉诸使用Laravel的storage_path,而且工作正常。

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

所以在我的具体类

 $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目录中的原始文件没有找到,即使它在那里...

我甚至不确定存储外观是否在后台使用VFS开始,即使它应该...