✅ Advanced Reflection Utilities
- Access and modify private and protected properties via reflection.
- Invoke inaccessible methods to expand testing coverage.
✅ Cross-Platform String Assertions
- Avoid false positives and negatives caused by Windows vs. Unix line ending differences.
- Normalize line endings for consistent string comparisons across platforms.
✅ File System Test Management
- Recursively clean files and directories for isolated test environments.
- Safe removal that preserves Git-tracking files (for example, '.gitignore', '.gitkeep').
Method 1: Using Composer (recommended)
Install the extension.
composer require --dev --prefer-dist php-forge/support:^0.2Add to your composer.json.
{
"require-dev": {
"php-forge/support": "^0.2"
}
}Then run.
composer update<?php
declare(strict_types=1);
use PHPForge\Support\TestSupport;
use PHPUnit\Framework\TestCase;
final class AccessPrivatePropertyTest extends TestCase
{
use TestSupport;
public function testInaccessibleProperty(): void
{
$object = new class () {
private string $secretValue = 'hidden';
};
$value = self::inaccessibleProperty($object, 'secretValue');
self::assertSame('hidden', $value, "Should access the private property and return its value.");
}
}<?php
declare(strict_types=1);
use PHPForge\Support\TestSupport;
use PHPUnit\Framework\TestCase;
final class InvokeProtectedMethodTest extends TestCase
{
use TestSupport;
public function testInvokeMethod(): void
{
$object = new class () {
protected function calculate(int $a, int $b): int
{
return $a + $b;
}
};
$result = self::invokeMethod($object, 'calculate', [5, 3]);
self::assertSame(8, $result, "Should invoke the protected method and return the correct sum.");
}
}<?php
declare(strict_types=1);
use PHPForge\Support\TestSupport;
use PHPUnit\Framework\TestCase;
final class NormalizeLineEndingsTest extends TestCase
{
use TestSupport;
public function testNormalizedComparison(): void
{
self::assertSame(
self::normalizeLineEndings("Foo\r\nBar"),
self::normalizeLineEndings("Foo\nBar"),
"Should match regardless of line ending style",
);
}
}<?php
declare(strict_types=1);
use PHPForge\Support\TestSupport;
use PHPUnit\Framework\TestCase;
final class RemoveFilesFromDirectoryTest extends TestCase
{
use TestSupport;
public function testCleanup(): void
{
$testDir = dirname(__DIR__) . '/runtime';
// clean up test artifacts (preserves '.gitignore' and '.gitkeep')
self::removeFilesFromDirectory($testDir);
self::assertTrue(true, "Should remove all files in the test directory while preserving Git-tracked files.");
}
}<?php
declare(strict_types=1);
use PHPForge\Support\TestSupport;
use PHPUnit\Framework\TestCase;
final class SetInaccessiblePropertyTest extends TestCase
{
use TestSupport;
public function testSetProperty(): void
{
$object = new class () {
private string $config = 'default';
};
// set private property for testing scenarios
self::setInaccessibleProperty($object, 'config', 'test-mode');
$newValue = self::inaccessibleProperty($object, 'config');
self::assertSame('test-mode', $newValue, "Should set the inaccessible property to 'test-mode'.");
}
}For comprehensive testing guidance, see: