【问题标题】:CakePHP / phpunit : how to mock a file uploadCakePHP / phpunit:如何模拟文件上传
【发布时间】:2017-01-25 06:15:00
【问题描述】:

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

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

这样做的正确方法是什么?

【问题讨论】:

    标签: php cakephp phpunit cakephp-3.0


    【解决方案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

    【讨论】:

      【解决方案2】:

      据我所知,CakePHP 神奇地结合了$_FILES$_POST 等的内容,因此我们从$this-&gt;request-&gt;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);
      

      【讨论】:

        猜你喜欢
        • 2018-10-10
        • 2020-10-15
        • 2013-08-31
        • 1970-01-01
        • 1970-01-01
        • 2012-12-26
        • 2011-01-14
        • 2017-06-29
        • 1970-01-01
        相关资源
        最近更新 更多