2016-09-16 255 views
5

我想寫一個端點的測試,這個端點需要一個附帶CSV文件的發佈請求。我知道要模擬這樣的發佈請求:CakePHP/phpunit:如何模擬文件上傳

$this->post('/foo/bar'); 

但我不知道如何添加文件數據。我試着手動設置$_FILES數組,但它沒有工作......

$_FILES = [ 
     'csvfile' => [ 
      'tmp_name' => '/home/path/to/tests/Fixture/csv/test.csv', 
      'name' => 'test.csv', 
      'type' => 'text/csv', 
      'size' => 335057, 
      'error' => 0, 
     ], 
]; 
$this->post('/foo/bar'); 

什麼是做到這一點的正確方法?

回答

0

從我所知道的,CakePHP神奇地結合了$_FILES,$_POST等的內容,因此我們訪問$this->request->data[...]中的每一個。您可以將信息傳遞給具有可選第二個參數的數據數組:

$data = [ 
     'csvfile' => [ 
      'tmp_name' => '/home/path/to/tests/Fixture/csv/test.csv', 
      'name' => 'test.csv', 
      'type' => 'text/csv', 
      'size' => 45, 
      'error' => 0, 
     ], 
]; 
$this->post('/foo/bar', $data); 
1

嘲弄核心PHP函數有點棘手。

我想你在你的文章模型中有這樣的東西。

public function processFile($file) 
{ 
    if (is_uploaded_file($file)) { 
     //process the file 
     return true; 
    } 
    return false; 
} 

而且你有相應的測試。

public function testProcessFile() 
{ 
    $actual = $this->Posts->processFile('noFile'); 
    $this->assertTrue($actual); 
} 

由於您在測試過程中沒有上傳任何東西,因此測試總是失敗。

您應該在PostsTableTest.php開頭添加第二個名稱空間,即使在單個文件中有更多的名稱空間也是不好的做法。

<?php 
namespace { 
    // This allows us to configure the behavior of the "global mock" 
    // by changing its value you switch between the core PHP function and 
    // your implementation 
    $mockIsUploadedFile = false; 
} 

比你應該有你的原始命名空間聲明在大括號格式。

namespace App\Model\Table { 

,你可以添加PHP核心方法被覆蓋

function is_uploaded_file() 
{ 
    global $mockIsUploadedFile; 
    if ($mockIsUploadedFile === true) { 
     return true; 
    } else { 
     return call_user_func_array('\is_uploaded_file',func_get_args()); 
    } 
} 

//other model methods 

} //this closes the second namespace declaration 

更多關於CakePHP的單元測試在這裏:http://www.apress.com/9781484212134