Is there any way of of making an admin-ajax request without the use of die()?

Pretty much what the title says.

I have a custom plugin written, that relies on the use of admin-ajax to handle various forms and actions. That’s all working fine, however as the various functions echo out responses I have to throw in a die() after the echo function. ie:

echo $return_string;
die();

All fine, however this unfortunately breaks my PHPUnit tests as throwing in a die() will kill the script and prevent the unit test from working. Without the die I receive the traditional 0 at the end of my response, which isn’t what I want. Have also tried the WP recommended:

wp_die();

Does anyone have any ideas on how to get around this?

2 Answers
2

If you use wp_die() you can utilize the tools included with WordPress’s PHPUnit test suite. The WP_Ajax_UnitTestCase provides the _handleAjax() method that will hook into the actions called by wp_die() and throw an exception, which will prevent die() from being called. I’ve written a tutorial on how to use WP_Ajax_UnitTestCase, which explains all of the features it provides, but here is a basic example:

class My_Ajax_Test extends WP_Ajax_UnitTestCase {

    public function test_some_option_is_saved() {

        // Fulfill requirements of the callback here...
        $_POST['_wpnonce'] = wp_create_nonce( 'my_nonce' );
        $_POST['option_value'] = 'yes';

        try {
            $this->_handleAjax( 'my_ajax_action' );
        } catch ( WPAjaxDieStopException $e ) {
            // We expected this, do nothing.
        }

        // Check that the exception was thrown.
        $this->assertTrue( isset( $e ) );

        // Check that the callback did whatever it is expected to do...
        $this->assertEquals( 'yes', get_option( 'some_option' ) );
    }
}

Note that technically speaking, this is integration testing rather than unit testing, as it tests a complete cross-section of the callback’s functionality, not just a single unit. This is how WordPress does it, but depending on the complexity of your callback’s code, you may also want to create true unit tests for it as well, probably abstracting portions of it out into other functions that you can mock.

Leave a Comment