CakePHP / phpunit:如何模拟文件上传

5

我正在尝试为一个需要带有附加CSV文件的POST请求的端点编写测试。我知道可以像这样模拟POST请求:

$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');

这应该怎么做才正确呢?
2个回答

2

模拟核心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


1
据我所知,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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接