Brain Monkey Tutorial: Simplified Unit Testing for WordPress


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!
Subscribe to my newsletter
Read articles from Junaid Bin Jaman directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Junaid Bin Jaman
Junaid Bin Jaman
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.