constup/vfs-testable

Interface and implementation of PHP's built-in functions that do not support vfsStream.

Maintainers

Package info

bitbucket.org/constup/vfs-testable

pkg:composer/constup/vfs-testable

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

1.0.2 2026-04-28 16:27 UTC

This package is auto-updated.

Last update: 2026-04-28 16:28:04 UTC


README

Description

Interface and implementation of PHP’s built-in functions that do not support vfsStream.

vfsStream works by registering a stream wrapper (vfs://). Any function that bypasses PHP’s stream layer and calls the OS directly will fail or return wrong results. This library provides a wrapper around affected functions for easier unit testing.

Installation

Constup\VfsTestable is supposed to be used in your production code as a wrapper around affected functions. It must be installed as your project's dependency (not dev dependency).

composer require constup/vfs-testable

Use

Instead of calling an unsupported built-in function directly, use the wrapper from this library.

Original code:

<?php

declare(strict_types=1);

namespace Constup\VfsTestableExamples;

readonly class MyClass
{
    public function myMethod(string $path): bool {
        $_path = realpath($path);

        return file_exists($_path . DIRECTORY_SEPARATOR . 'some_file.txt');
    }
}

With VfsTestable:

<?php

declare(strict_types=1);

namespace Constup\VfsTestableExamples;

use Constup\VfsTestable\VfsTestableInterface;

readonly class MyClassVfsTestable
{
    public function __construct(
        private VfsTestableInterface $vfsTestable
    ) {}

    public function myMethod(string $path): bool {
        $_path = $this->vfsTestable->realpath($path);

        return file_exists($_path . DIRECTORY_SEPARATOR . 'some_file.txt');
    }
}

You can then mock it using PHP Unit:

<?php

declare(strict_types = 1);

namespace Constup\VfsTestable\Tests;

use Constup\VfsTestable\VfsTestableInterface;
use Constup\VfsTestableExamples\MyClassVfsTestable;
use org\bovigo\vfs\vfsStream;
use PHPUnit\Framework\TestCase;

class MyClassVfsTestableTest extends TestCase
{
    /**
     * This test shows that we are still using `vfsStream` file system for other functions, like `file_exists()` while
     * mocking `realpath()` using `VfsTestableInterface`.
     */
    public function test_myMethod_vfsStream_FileExists(): void
    {
        $root = vfsStream::setup('root', null, [
            'some' => [
                'path' => [
                    'some_file.txt' => 'some content',
                ],
            ],
        ]);

        $path = vfsStream::url('root/some/path');
        $realpathMockResult = $root->url() . '/some/path';

        $vfsTestableMock = $this->createMock(VfsTestableInterface::class);
        $vfsTestableMock
            ->expects($this->once())
            ->method('realpath')
            ->with($path)
            ->willReturn($realpathMockResult);

        $myClassVfsTestable = new MyClassVfsTestable($vfsTestableMock);

        $this->assertTrue($myClassVfsTestable->myMethod($path));
    }
}

If you want to run or debug the example, clone this repository and take a look at the examples directory and its tests. Note that tests are excluded from the composer library and are not available in your vendor directory.

License

MIT License

Supporting development

buymeacoffee.com ko-fi.com