Mocking tempnam() with vfsstream
1 answer
This turned out to be a more difficult question to address than I initially thought! After many attempts at finding a way to use tempnam()
with vfsStream, I only just now found out from the vfsStream documentation that tempnam()
is one of those types of functions that is among the "thin wrappers around the native C functions". These types of functions evidently do not support "stream wrappers like vfs" (from the documentation).
Thus, it does not appear that you can use vfsStream with the tempnam()
function.
I don't know if mocking tempnam()
using another tool like PHP-Mock would help for your situation. Here is a possible example of what mocking tempnam()
with PHP-Mock could look like, though.
mock.php
<?php
namespace example;
# ref: https://getcomposer.org/doc/01-basic-usage.md
require __DIR__ . '/vendor/autoload.php';
# ref: https://github.com/php-mock/php-mock#php-mock-api
use phpmock\MockBuilder;
$builder = new MockBuilder();
$builder->setNamespace(__NAMESPACE__)
->setName("tempnam")
->setFunction(
function() {
return '/tmp/file_abc';
}
);
$mock = $builder->build();
$mock->enable();
echo(assert(tempnam() == '/tmp/file_abc'));
// result should be 1
composer.json
{
"require-dev": {
"php-mock/php-mock": "^2.3"
}
}
For reference, the code that I was using earlier when trying to find a method to use vfsStream with tempnam()
looked like this:
Example.php
<?php
#ref: https://github.com/bovigo/vfsStream/wiki/Example
#ref: https://www.php.net/manual/en/function.tempnam.php
namespace Example;
class Example
{
public function __construct()
{
}
public function addFile($directory, $filename)
{
$tmpfname = tempnam($directory, $filename);
$handle = fopen($tmpfname, "w");
fwrite($handle, "Hello, world in a file!");
fclose($handle);
}
}
ExampleTest.php
<?php
# ref: https://github.com/bovigo/vfsStream/wiki/Example
namespace Example;
require_once 'Example.php';
use PHPUnit\Framework\TestCase;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
class ExampleTest extends TestCase
{
private $testDirectory;
public function setUp(): void
{
$this->testDirectory = vfsStream::setup('test_directory');
}
public function testFileIsAdded()
{
$e = new Example();
$e->addFile(vfsStream::url('test_directory'), 'test_file');
$this->assertTrue($this->testDirectory->hasChild('test_file'));
}
}
composer.json
{
"require": {
"mikey179/vfsstream": "^1.6"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
}
}
And when running the ExampleTest.php file, the result was this (with username omitted):
$ vendor/phpunit/phpunit/phpunit ExampleTest.php
PHPUnit 9.5.2 by Sebastian Bergmann and contributors.
E 1 / 1 (100%)
Time: 00:00.027, Memory: 4.00 MB
There was 1 error:
1) Example\ExampleTest::testFileIsAdded
tempnam(): file created in the system's temporary directory
/home/username/programming/q8/Example.php:16
/home/username/programming/q8/ExampleTest.php:24
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
0 comments