Brain-WP/BrainMonkey

How to mock the WordPress `add_shortcode()` function?

emeraldjava opened this issue · 2 comments

Hi,
In my wordpress plugin that I am trying to unit test with BrainMonkey, i have classes which registers shortcodes with the wordpress API

`class RaceResultShortcode {

function __construct() {
    add_shortcode('bhaa_race_results'   ,array($this,'bhaa_race_results_shortcode'));
    add_shortcode('bhaa_race_title'     ,array($this,'bhaa_race_title_shortcode'));
}`

in my Test, i see this error where the 'add_shortcode()' is an undefined function

Error : Call to undefined function BHAA\core\race\add_shortcode() C:\emeraldjava\bhaa_wordpress_plugin\src\core\race\RaceResultShortcode.php:14 C:\emeraldjava\bhaa_wordpress_plugin\src\Main.php:65 C:\emeraldjava\bhaa_wordpress_plugin\tests\MainTest.php:13

Is there a suggested workaround for this scenario?
Thanks in advance.
Paul

widoz commented

Hi @emeraldjava you can patch the add_shortcode with the function when or in case you need expectation with expect.

The differences are:

With when you patch the function because you need a returned value or simply you need the function exists when called, for more info see https://brain-wp.github.io/BrainMonkey/docs/functions-when.html

With expect you can ensure your logic is respected and also you can use the expectations to actually tests as part of the assertions.
For example, if you want to be sure a certain function is called and how many times and with which arguments to ensure the correctness of your logic.
For more info about https://brain-wp.github.io/BrainMonkey/docs/functions-expect.html

In your case (even if I think better to introduce the shortcode into a different method raither than the constructor) you can use when.

For example:

use \Brain\Monkey\Functions;

class MyTest extends TestCase {
    public function testSomething() {
        Functions\when('add_shortcode')
            ->justReturn(true);

        // ... The rest of the logic    
    }
}

I used to call justReturn to return a simple value even though in this case you don't need to check against anything.

But if you want to ensure the add_shortcode is called, you can for example:

use \Brain\Monkey\Functions;

class MyTest extends TestCase {
    public function testSomething() {
        Functions\expect('add_shortcode')
            ->twice()
            ->with(\Mockery::type('string'), \Mockery::type('array'));

        // ... The rest of the logic
    }
}

This is a pretty specific question, so I doubt it could be useful for others. I'm closing it to keep issue list cleaner.