2017-05-04 118 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開始,即使它應該...