I am very new on PHPUnit testing, and I need some help if posible.
I have install a plugin in WordPress, for unit testing, that is based on PHPUnit Framework. I am currently building a WordPress Plugin that using AJAX calls, in order to interact with the WordPress data.
In my plugin, I have create a Class that creating some add_action(‘wp_ajax_actionname’, array(__CLASS__, ‘functionName’))
the functionName looks like the following:
function functionName()
{
global $wpdb;
if(wp_verify_nonce($_POST['s'], 'cdoCountryAjax') != false)
{
$zones = $wpdb->get_results(
$wpdb->prepare(
"
SELECT
zone_id AS ID,
name AS Name
FROM
" . $wpdb->prefix . "cdo_zone
WHERE
country_id = %d
",
$_POST['id']
)
);
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
$results = array();
foreach($zones as $zone)
{
$results[$zone->ID] = $zone->Name;
}
echo json_encode($results);
}
die(-1);
}
The above function it gets the Query results returned into an Object, and I echoed by using the json_encode function.
The question is, how can I test the above method ? Is there a way to test it ?
There are two not-so-test-friendly things you will have to deal with:
The output generation with echo. For this, you can wrap the function call in question inside an
ob_start()
…ob_end_clean()
pair to get the output that would have been echoed.Edit:
As it turns out, there’s already a built-in support for this in the library, check out the Testing Output section of the manual.
The other problem you have to deal with is the
die(-1)
at the end. You can use theset_exit_overload()
function provided in php test helpers to disable it’s effect, so your test process won’t die along with the code. This is a little harder to set up (you will need a C compiler). If that can’t work for you you could be out of luck in case you can’t change the code to something more test friendly. (I’m not too familiar with wordpress but for ajax plugins thisdie()
usage seems recommended). As a last resort, you could try running the script as a subprocess withpopen()
orexec()
and get the result that way (you will have to write a file that includes the source and calls the function that will not be tested).In the ideal case this would look something like this:
In the worst case, maybe something like:
And inside the
tested_function_runner.php
:You can of course make this runner script more general with parameters passed and used from
$argv
.When you feel like it, please also take a look at the Output Test features of PHPUnit, they are great.
(As complex857 said, there are many bits and pieces to this issue, but for the output testing, lean on this PHPUnit built-in feature.)
The manual is eloquent and helpful: https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.output