模拟单元测试中的WP_CLI静态方法

时间:2020-12-07 作者:dingo_d

我正在为正在开发的库编写单元测试(而不是集成)。在那里,我们创建了一些我想测试的WP-CLI命令。它们中的大多数只是重命名东西,将东西从lib复制并粘贴到项目中。

当事情成功与否WP_CLI::success() 或使用类似的方法将消息输出给用户(log, warningerror).

所以我想做的就是输出这些方法的内容,这样我就可以测试所需的输出是否发生了。

使用Mockery 我试着做了以下事情

// Mock certain WPCLI methods.
$wpCliMock = \\Mockery::mock(\'alias:WP_CLI\');
$wpCliMock
    ->shouldReceive(\'success\')
    ->andReturnArg(0);
但它似乎不起作用,因为我的测试Call to a member function fetchMock() on null 错误指向成功方法。

测试位于here. 我正在使用Pest作为我的测试框架。

1 个回复
最合适的回答,由SO网友:dingo_d 整理而成

所以我使用PEST 作为我的测试框架,如果我只是在helpers中定义mock,它们将不会被正确调用,因为在每次测试之后,WPCLI可能会自动加载。所以我补充道

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

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

    $wpCliMock
        ->shouldReceive(\'error\')
        ->andReturnArg(0);
});
在我的测试中,现在一切都正常通过了。

编辑,因为我实际上没有使用真正的WP\\U CLIsuccesserror like命令通常会将内容输出到STDERR或STDOUT。这意味着你的退货实际上不会退货(andReturnArg(0) 零件)。

因此,您实际上可以尝试查看传递了哪些参数,并将这些参数设置为temp env var,然后可以对其进行测试。例如:

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

    $wpCliMock
        ->shouldReceive(\'error\')
        ->andReturnUsing(function ($message) {
            putenv("ERROR_HAPPENED={$message}");
        });
现在如果在代码中

\\WP_CLI::error(\'Error has happened!\');
您可以在测试中使用

$this->assertSame(\'Error has happened!\', getenv(\'ERROR_HAPPENED\'));
只需确保清理了temp env var,以免污染其他测试。