jeudi 19 novembre 2015

PHPUnit test a function that write in file and check the content into created file

I am contributing on sonata/exporter project, a sonata component using for export data in one of the available formats (CSV, Json, Xml, Xls...).

I work on a custom writer for convert boolean values in "yes"/"no" strings before use an other writer like CsvWriter or XlsWriter.

It's my first experience with phpunit. All unit tests made on the existing Writers use this logic : - Create a file. - Write data in file using the good format. - Make an assertEquals with file_get_contents(filename) and the expected string.

So, I've written this test :

public function setUp()
{
    $this->filename = 'formatedbool.xls';
    $this->sampleWriter = new XlsWriter($this->filename, false);
    $this->trueLabel = 'oui';
    $this->falseLabel = 'non';

    if (is_file($this->filename)) {
        unlink($this->filename);
    }
}

public function testValidDataFormat()
{
    $writer = new FormatedBoolWriter($this->sampleWriter, $this->trueLabel, $this->falseLabel);
    $writer->open();
    $writer->write(array('john', 'doe', false, true));
    $writer->close();

    $expected = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name=ProgId content=Excel.Sheet><meta name=Generator content="http://ift.tt/1SHypNE"></head><body><table><tr><td>john</td><td>doe</td><td>non</td><td>oui</td></tr></table></body></html>';
    $this->assertEquals($expected, trim(file_get_contents($this->filename)));
}

On submit my PR on the project, the owner say me :

just use a mock with expected method call and check calling argument, this will avoid creating the file. see http://ift.tt/1PBXAmX

I have begin to rewrite tests using a Mock :

public function testValidDataFormat()
{
    $data = array('john', 'doe', false, true);
    $expected = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name=ProgId content=Excel.Sheet><meta name=Generator content="http://ift.tt/1SHypNE"></head><body><table><tr><td>john</td><td>doe</td><td>non</td><td>oui</td></tr></table></body></html>';
    $mock = $this->getMockBuilder('Exporter\Writer\FormatedBoolWriter')
                 ->setConstructorArgs(array($this->sampleWriter, $this->trueLabel, $this->falseLabel))
                 ->setMethods(array('open', 'write', 'close'))
                 ->getMock();
    $mock->open();
    $mock->expects($this->once())
        ->method('write')
        ->withConsecutive(
            array($this->equalTo($data)),
            array($this->assertEquals($data, $data))
        );
    $mock->write($data);
    $mock->close();
    $this->assertEquals($expected, trim(file_get_contents($this->filename)));
}

But I have an error on file_get_contents . The "write" method just write in a file and return nothing.

I think the project owner want I test the data after converting bools, but before writing in file. How can I check the result of the file content without really create it ? Or simply access to my $data during the method call ?

Aucun commentaire:

Enregistrer un commentaire