Testing

Running Tests

composer test

Test Structure

tests/
+-- bootstrap.php
+-- Unit/
    +-- HookManagerTest.php

Mocking WordPress Functions

Create a bootstrap that mocks WordPress hook functions:

// tests/bootstrap.php
<?php

require_once dirname(__DIR__) . '/vendor/autoload.php';

// Track hook calls for testing
$GLOBALS['wp_actions'] = [];
$GLOBALS['wp_filters'] = [];

if (!function_exists('add_action')) {
    function add_action($tag, $callback, $priority = 10, $args = 1) {
        $GLOBALS['wp_actions'][$tag][] = [
            'callback' => $callback,
            'priority' => $priority,
        ];
    }
}

if (!function_exists('add_filter')) {
    function add_filter($tag, $callback, $priority = 10, $args = 1) {
        $GLOBALS['wp_filters'][$tag][] = [
            'callback' => $callback,
            'priority' => $priority,
        ];
    }
}

if (!function_exists('do_action')) {
    function do_action($tag, ...$args) {
        $GLOBALS['fired_actions'][$tag] = $args;
    }
}

if (!function_exists('apply_filters')) {
    function apply_filters($tag, $value, ...$args) {
        $GLOBALS['applied_filters'][$tag] = $value;
        return $value;
    }
}

if (!function_exists('remove_action')) {
    function remove_action($tag, $callback, $priority = 10) {
        return true;
    }
}

if (!function_exists('remove_filter')) {
    function remove_filter($tag, $callback, $priority = 10) {
        return true;
    }
}

Example Test

class HookManagerTest extends TestCase
{
    private MockContext $context;
    private HookManager $hooks;

    protected function setUp(): void
    {
        $GLOBALS['wp_actions'] = [];
        $GLOBALS['wp_filters'] = [];

        $this->context = new MockContext('test_');
        $this->hooks = new HookManager($this->context);
    }

    public function testWpActionNotPrefixed(): void
    {
        $this->hooks->wpAction('init', fn() => null);

        $this->assertArrayHasKey('init', $GLOBALS['wp_actions']);
    }

    public function testActionIsPrefixed(): void
    {
        $this->hooks->action('saved', fn() => null);

        $this->assertArrayHasKey('test_saved', $GLOBALS['wp_actions']);
    }
}