Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP / phpunit : how to mock a file upload

I'm trying to write tests for an endpoint that expects a post request with an attached CSV file. I know to simulate the post request like this:

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

But I can't figure out how to add the file data. I tried manually setting the $_FILES array but it didn't work...

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

What's the right way to do this?

like image 770
emersonthis Avatar asked Oct 19 '22 01:10

emersonthis


1 Answers

Mocking core PHP functions is a little bit tricky.

I guess you have something like this in your posts model.

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

And you have a corresponding test like this.

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

As you do not upload anything during the test process, the test will always fail.

You should add a second namespace at the begining of your PostsTableTest.php, even having more namespaces in a single file is a bad practice.

<?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;
}

Than you should have your original namespace declaration in curly bracket format.

namespace App\Model\Table {

And you can add the PHP core method to be overwritten

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

More on CakePHP unit testing here: http://www.apress.com/9781484212134

like image 58
rrd Avatar answered Oct 21 '22 03:10

rrd