2016-09-16 259 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