PHPUnit 如何测试包含 check_admin_referer() 的 Wordpress 函数?
How would you PHPUnit test a Wordpress function containing check_admin_referer()?
我刚刚开始使用 Wordpress 学习 PHPUnit。我有一个从 change.org 获取请愿数据的插件。其中一个管理 class 函数验证来自 Wordpress 管理区域的设置,并调用 `check_admin_referer() 作为此验证的一部分。
public function sc_validate_settings() {
//check nonce field is valid
check_admin_referer($this->plugin_name, 'security');
//get new settings
$settings = $this->sc_clean_new_settings();
//validate url
$valid_url = $this->sc_validate_url($settings['petition_url']);
//validate api_key
$valid_api_key = $this->sc_validate_api_key($settings['petition_api_key']);
if ($valid_url && $valid_api_key) {
$this->clean_settings = $settings;
return true;
}
return false;
}
如果我注释掉这个 PHPUnit 测试通过 check_admin_referer()
但如果不注释我就无法通过。
public function testValidateSettings() {
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
我试过在 tests/bootstrap.php 中通过 wp_nonce_field()
通过 $_POST
手动设置随机数、动作和 _wp_http_referer 并在测试中class 本身。我读过一些关于 mock objects/methods 的内容,但不太明白在这种情况下如何使用它们。
我可能完全误解了这一切的工作原理,但我们将不胜感激任何帮助!
问题是在命令行模式下测试运行,当然,当前用户没有在那里进行身份验证。
有几种方法可以让它发挥作用。一种选择是存根 auth-check 函数 check_admin_referer()
或其基础 wp_verify_nonce()
。但这不是最好的方法,因为那里的测试具有集成风格,而存根更像是一种单元测试方法。
一个好的解决方案是对用户进行身份验证以使测试通过。你可以像这样相对容易地做到这一点:
public function testValidateSettings() {
$_REQUEST['security'] = wp_create_nonce($this->plugin_admin->plugin_name);
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
我不确定 $this->plugin_admin->plugin_name
是否有效,因为它可能是私有的 属性。所以你可以将它作为硬编码字符串传递:
public function testValidateSettings() {
$_REQUEST['security'] = wp_create_nonce('whatever your plugin name is');
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
在测试后进行清理也很好,因此您绝对应该在测试用例中包含它:
public function tearDown() {
unset($_REQUEST['security']);
}
我认为您不需要在测试后清除新创建的随机数,因为 WP 原始测试也不会清除它。
太好了。
改善
如果测试用例中的所有测试都需要身份验证,您可能希望将随机数创建放入 setUp()
- 这将使测试用例更漂亮,因为拆卸代码将与设置代码匹配:
public function setUp() {
$_REQUEST['security'] = wp_create_nonce('whatever your plugin name is');
}
public function tearDown() {
unset($_REQUEST['security']);
}
public function testValidateSettings() {
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
建议
安装 Xdebug 并通过您的 IDE 连接到它 - 这将帮助您逐步检查代码并查看有什么不符合您的预期。这比盲目地与所有那些 nonces、http referrers 等作斗争要好。
备注
WP 代码很伤心。全局命名空间中的大量函数、缺乏 OOP、没有完整的请求处理周期(例如,意外的 die()
)- 真的很令人沮丧,因为它使代码库的扩展和测试变得非常困难。
所以请准备好与代码进行更多的战斗:)
我刚刚开始使用 Wordpress 学习 PHPUnit。我有一个从 change.org 获取请愿数据的插件。其中一个管理 class 函数验证来自 Wordpress 管理区域的设置,并调用 `check_admin_referer() 作为此验证的一部分。
public function sc_validate_settings() {
//check nonce field is valid
check_admin_referer($this->plugin_name, 'security');
//get new settings
$settings = $this->sc_clean_new_settings();
//validate url
$valid_url = $this->sc_validate_url($settings['petition_url']);
//validate api_key
$valid_api_key = $this->sc_validate_api_key($settings['petition_api_key']);
if ($valid_url && $valid_api_key) {
$this->clean_settings = $settings;
return true;
}
return false;
}
如果我注释掉这个 PHPUnit 测试通过 check_admin_referer()
但如果不注释我就无法通过。
public function testValidateSettings() {
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
我试过在 tests/bootstrap.php 中通过 wp_nonce_field()
通过 $_POST
手动设置随机数、动作和 _wp_http_referer 并在测试中class 本身。我读过一些关于 mock objects/methods 的内容,但不太明白在这种情况下如何使用它们。
我可能完全误解了这一切的工作原理,但我们将不胜感激任何帮助!
问题是在命令行模式下测试运行,当然,当前用户没有在那里进行身份验证。
有几种方法可以让它发挥作用。一种选择是存根 auth-check 函数 check_admin_referer()
或其基础 wp_verify_nonce()
。但这不是最好的方法,因为那里的测试具有集成风格,而存根更像是一种单元测试方法。
一个好的解决方案是对用户进行身份验证以使测试通过。你可以像这样相对容易地做到这一点:
public function testValidateSettings() {
$_REQUEST['security'] = wp_create_nonce($this->plugin_admin->plugin_name);
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
我不确定 $this->plugin_admin->plugin_name
是否有效,因为它可能是私有的 属性。所以你可以将它作为硬编码字符串传递:
public function testValidateSettings() {
$_REQUEST['security'] = wp_create_nonce('whatever your plugin name is');
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
在测试后进行清理也很好,因此您绝对应该在测试用例中包含它:
public function tearDown() {
unset($_REQUEST['security']);
}
我认为您不需要在测试后清除新创建的随机数,因为 WP 原始测试也不会清除它。
太好了。
改善
如果测试用例中的所有测试都需要身份验证,您可能希望将随机数创建放入 setUp()
- 这将使测试用例更漂亮,因为拆卸代码将与设置代码匹配:
public function setUp() {
$_REQUEST['security'] = wp_create_nonce('whatever your plugin name is');
}
public function tearDown() {
unset($_REQUEST['security']);
}
public function testValidateSettings() {
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
建议
安装 Xdebug 并通过您的 IDE 连接到它 - 这将帮助您逐步检查代码并查看有什么不符合您的预期。这比盲目地与所有那些 nonces、http referrers 等作斗争要好。
备注
WP 代码很伤心。全局命名空间中的大量函数、缺乏 OOP、没有完整的请求处理周期(例如,意外的 die()
)- 真的很令人沮丧,因为它使代码库的扩展和测试变得非常困难。
所以请准备好与代码进行更多的战斗:)