Mocking WP_CLI static methods in unit tests

So I am using PEST as my testing framework, and if I just define my mocks in the helpers, they won’t be called correctly, because the WPCLI will probably be autoloaded after that on each test. So I added

beforeEach(function () {
    $wpCliMock = \Mockery::mock('alias:WP_CLI');

    $wpCliMock
        ->shouldReceive('success')
        ->andReturnArg(0);

    $wpCliMock
        ->shouldReceive('error')
        ->andReturnArg(0);
});

Inside my tests, and now everything is passing correctly.

EDIT

Since I’m not actually using real WP_CLI, and the success or error like commands will usually output things to STDERR or STDOUT. That means your return won’t actually return anything (andReturnArg(0) part).

So you can actually try to see what arguments are passed and set these to the temp env var that you can then test against. For instance:

    $wpCliMock = \Mockery::mock('alias:WP_CLI');

    $wpCliMock
        ->shouldReceive('error')
        ->andReturnUsing(function ($message) {
            putenv("ERROR_HAPPENED={$message}");
        });

Now if inside your code you have

\WP_CLI::error('Error has happened!');

you’ll be able to test this in your test using

$this->assertSame('Error has happened!', getenv('ERROR_HAPPENED'));

Just make sure you clean up the temp env var not to pollute other tests.