Skip to main content

Command Palette

Search for a command to run...

Brain Monkey Tutorial: Simplified Unit Testing for WordPress

Updated
3 min read
Brain Monkey Tutorial: Simplified Unit Testing for WordPress
J

Hello! I'm a software developer with over 6 years of experience, specializing in React and WordPress plugin development. My passion lies in crafting seamless, user-friendly web applications that not only meet but exceed client expectations. I thrive on solving complex problems and am always eager to embrace new challenges. Whether it's building robust WordPress plugins or dynamic React applications, I bring a blend of creativity and technical expertise to every project.

Unit testing in WordPress can be tricky due to its reliance on global functions and hooks. Brain Monkey simplifies this process by allowing you to mock WordPress functions, hooks, and filters easily. This tutorial will guide you through setting up a full WordPress project for Brain Monkey, along with detailed examples of unit testing real-world scenarios.

1. Prerequisites

Before starting, ensure you have the following installed:

  • PHP (7.4 or later recommended)

  • Composer

  • PHPUnit (installed via Composer)

  • A basic understanding of WordPress development

2. Setting Up the Project

Step 1: Create a WordPress Plugin Project

Create a folder for your plugin:

mkdir wp-brain-monkey-plugin
cd wp-brain-monkey-plugin

Step 2: Initialize Composer

Run the following command to create a composer.json file:

composer init

Follow the prompts and accept the defaults. Once complete, install the required dependencies.

Step 3: Install Brain Monkey and PHPUnit

Run:

composer require --dev brain/monkey phpunit/phpunit

This will install Brain Monkey and PHPUnit in the vendor directory.

Step 4: Set Up PHPUnit Configuration

Create a phpunit.xml file in the project root:

<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd" bootstrap="tests/bootstrap.php">
    <testsuites>
        <testsuite name="Plugin Tests">
            <directory>./tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

Step 5: Create a Test Bootstrap File

Create a tests/bootstrap.php file:

<?php

require_once __DIR__ . '/../vendor/autoload.php';

use Brain\Monkey;

// Set up Brain Monkey before each test
Brain\Monkey\setUp();

// Tear down Brain Monkey after each test
Brain\Monkey\tearDown();

Step 6: Create the Plugin File

Create my-plugin.php in the project root:

<?php
/*
Plugin Name: Brain Monkey Example Plugin
Description: A plugin to demonstrate Brain Monkey unit testing.
Version: 1.0
Author: Your Name
*/

function my_plugin_add_greeting($name) {
    return apply_filters('my_plugin_greeting', "Hello, $name!");
}

function my_plugin_register_shortcode() {
    add_shortcode('greeting', function ($atts) {
        $atts = shortcode_atts(['name' => 'Guest'], $atts);
        return my_plugin_add_greeting($atts['name']);
    });
}
add_action('init', 'my_plugin_register_shortcode');

3. Writing Unit Tests with Brain Monkey

Step 1: Create a Test Class

Create a tests/TestMyPlugin.php file:

<?php

use PHPUnit\Framework\TestCase;
use Brain\Monkey\Functions;

class TestMyPlugin extends TestCase {
    public function setUp(): void {
        parent::setUp();
        Brain\Monkey\setUp();
    }

    public function tearDown(): void {
        Brain\Monkey\tearDown();
        parent::tearDown();
    }

    // Your tests will go here
}

Step 2: Write Unit Tests

Test 1: Mocking apply_filters

public function test_my_plugin_add_greeting() {
    Functions\when('apply_filters')->justReturn('Hello, John!');

    $result = my_plugin_add_greeting('John');

    $this->assertEquals('Hello, John!', $result);
}

Test 2: Mocking a Hook (add_shortcode)

public function test_my_plugin_register_shortcode() {
    Functions\expect('add_shortcode')
        ->once()
        ->with('greeting', Functions\type('callable'));

    my_plugin_register_shortcode();
}

Test 3: Testing Shortcode Execution

public function test_shortcode_output() {
    Functions\when('apply_filters')->justReturn('Hello, Guest!');

    $output = my_plugin_add_greeting('Guest');

    $this->assertEquals('Hello, Guest!', $output);
}

Test 4: Mocking shortcode_atts

public function test_shortcode_atts() {
    Functions\when('shortcode_atts')->justReturn(['name' => 'John']);

    $atts = shortcode_atts(['name' => 'Guest'], ['name' => 'John']);

    $this->assertEquals(['name' => 'John'], $atts);
}

Test 5: Mocking add_action

public function test_my_plugin_init_hook() {
    Functions\expect('add_action')->once()->with('init', 'my_plugin_register_shortcode');

    my_plugin_register_shortcode();
}

Test 6: Testing Filters with Parameters

public function test_filter_with_parameters() {
    Functions\when('apply_filters')->alias(function ($tag, $value) {
        if ($tag === 'my_plugin_greeting') {
            return str_replace('Hello', 'Hi', $value);
        }
        return $value;
    });

    $result = my_plugin_add_greeting('John');

    $this->assertEquals('Hi, John!', $result);
}

Test 7: Testing Multiple Hooks

public function test_multiple_hooks() {
    Functions\expect('add_action')
        ->twice()
        ->withConsecutive(
            ['init', 'my_plugin_register_shortcode'],
            ['wp_footer', 'my_plugin_footer_callback']
        );

    add_action('init', 'my_plugin_register_shortcode');
    add_action('wp_footer', 'my_plugin_footer_callback');
}

4. Running the Tests

Run PHPUnit with the following command:

vendor/bin/phpunit

Sample Output:

PHPUnit 9.5.0 by Sebastian Bergmann and contributors.

.......                                                           7 / 7 (100%)

Time: 00:00.150, Memory: 6.00 MB

OK (7 tests, 7 assertions)

5. Conclusion

This tutorial demonstrates how Brain Monkey makes unit testing for WordPress plugins simple and effective. By mocking WordPress-specific functions and hooks, you can write robust, isolated tests for your plugins.

As you gain familiarity, you can extend this setup to include integration tests using tools like WP-Browser and PHPUnit. Happy testing!

S

Hey. I tried your tutorial but I got a lot of PHP errors and the tests don't run. I can't send you a link to the output since it's my first comment. The first error is:

"1) MyPluginTest::test_my_plugin_add_greeting Error: Call to undefined function my_plugin_add_greeting()"

All the rest are the same as the plugin file is not loading. Also there is an error about Brain Monkey: Error: Call to undefined method Mockery\Expectation::withConsecutive().

Is there something I'm missing? Hope you can help.

WordPress

Part 1 of 15

Unlock the full potential of WordPress with this series, covering everything from core features to theme and plugin development. Each post simplifies concepts to help you create powerful WordPress sites with ease. Let’s dive in!

Up next

Integrating Monolog into a WordPress Plugin Using the WPPB Boilerplate

Logging is an essential part of any application or plugin. It helps developers track errors, debug issues, and monitor plugin behavior in real-time. When developing a WordPress plugin, using a robust logging library like Monolog can significantly enh...

More from this blog

L

Learn More About Programming

67 posts

I'm a developer with 6+ years of experience in React, React Native, and WordPress plugins, passionate about crafting user-friendly apps and solving challenges with creativity and expertise!