我刚开始用Wordpress学习PHPUnit。我有一个插件可以从change.org获取请愿数据。其中一个管理类函数验证来自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;
}
如果我注释掉check_admin_referer()
,那么这个PHPUnit测试会通过,但如果没有,我就无法通过。
public function testValidateSettings() {
$this->assertTrue($this->plugin_admin->sc_validate_settings());
}
我尝试在tests / bootstrap.php和测试类本身中通过wp_nonce_field()
手动设置nonce,action和_wp_http_referer并通过$_POST
设置。我已经阅读了一些关于模拟对象/方法的内容,但是在这个实例中并没有看到它们如何被使用。
我可能完全误解了这一切是如何运作的,但是我们将非常感谢任何帮助!
答案 0 :(得分:6)
问题是测试在命令行模式下运行,当然,当前用户未在那里进行身份验证。
如何使其发挥作用还有几种选择。一种选择是存根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']);
}
我不认为你需要在测试后清理新创建的nonce,因为WP原始测试也不会清除它。
这很漂亮。
<强>改进强>
如果测试用例中的所有测试都需要身份验证,您可能希望将nonce-creation设置为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连接到它 - 这将帮助您逐步完成代码,看看哪些内容无法正常工作。这比盲目地与所有这些nonce,http引用等等进行斗争更好。
注意强>
WP代码非常难过。全局命名空间中的大量函数列表,缺少OOP,没有完整的请求处理周期(例如,意外的die()
) - 实在令人沮丧,因为它使得代码库的扩展和测试非常困难。
所以准备好与代码进行更多的战斗:)