Small step in WordPress test-ability

Don’t ask, don’t tell

One of WordPress coding common practices, seen all over the web, is the one pictured in the code below. In short the function, here used inside a class and hooked in the __construct method, conditionally queues a script on the plugin options page.
Since so much WordPress code is written without any idea, or notion, of testing the class methods in any way the function below says nothing of it’s operations because no one asks.

));
/**
 * Enqueues the scripts needed by the plugin
 */
public function enqueue_settings_scripts()
{
    if (is_admin() and $this->conditionals->is_plugin_settings_page()) {
        $this->functions->wp_enqueue_script('admin-ajax-save_functions', $this->assets_path . '/js/admin-ajax-save_functions.js', array(
            'jquery'
        ));
    }
}

But I’m expecting

Since I write code, WordPress one, trying to adopt Test-driven Development practices the silence the method above lives in is not good. Bare-bones testing requires, if not covering all the possible code, to test conditionals as a bare minimum. To test the above function in code I’m using an Adapter class, the functions object, and can mock it in code and setup an expectation in PHPUnit like this:

$mock_functions->expects($this->once())->method('wp_enqueue_script')->with($this->equalTo($arg1), $this->equalTo($arg2), ...);

Of course the expectation is matched with a proper conditional setup to simulate, in this case, that the page is the one that’s supposed to trigger the script loading.

I could also ask and the code could tell

The PHPUnit solution above works but things could be made way easier by returning something in the above method like this:

/**
 * Enqueues the scripts needed by the plugin
 * @return array An array containing the handles of the loaded scripts.
 */
public function enqueue_settings_scripts()
{
    $enq = array();
    // load the script on the plugins options page alone
    if (is_admin() and $this->conditionals->is_plugin_settings_page()) {
        $script_name = 'admin-ajax-save_functions';
        wp_enqueue_script($script_name, $this->assets_path . '/js/admin-ajax-save_functions.js', array(
            'jquery'
        ));
        $enq[] = $script_name;
    }

    return $enq;
}

Now testing to see if the script was loaded where it’s supposed to and has not been loaded where it’s not supposed to it’s as easy as setting up the mock environment and calling the function.

public function testLoadsOnPluginPage(){
    // create the mock conditions to have the plugin load the script
    $this->setPageToPluginOne();
    // call the function on the Subject Under Test and test the results
    $this->assertContains('admin-ajax-save_functions', $sut->enqueue_settings_scripts());
}

Could help supporting

Sure the return value is not of much use in normal production code but still it could be of some use in error logging and supporting.

/**
 * Enqueues the scripts needed by the plugin
 * @return array An array containing the handles of the loaded scripts.
 */
public function enqueue_settings_scripts()
{
    $enq = array();
    // load the script on the plugins options page alone
    if (is_admin() and $this->conditionals->is_plugin_settings_page()) {
        $script_name = 'admin-ajax-save_functions';
        $exit = wp_enqueue_script($script_name, $this->assets_path . '/js/admin-ajax-save_functions.js', array(
            'jquery'
        ));
        $enq[] = $script_name;
    }
    // log loaded scripts for support purposes
    $this->logger->logLoadedScripts($enq);

    return $enq;
}