2016-08-12 129 views
5

我剛開始用Wordpress學習PHPUnit。我有一個從change.org獲取請願數據的插件。其中一個管理類功能驗證Wordpress管理區域的設置,並在此驗證中調用`check_admin_referer()。如果我註釋掉check_admin_referer(),但我不能讓它通過,如果不PHPUnit如何測試一個包含check_admin_referer()的Wordpress函數?

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的測試通過。

public function testValidateSettings() {  

    $this->assertTrue($this->plugin_admin->sc_validate_settings()); 

    } 

我試圖通過$_POST在測試/ bootstrap.php中,並在測試類的手動和通過wp_nonce_field()設置一個隨機數,動作和_wp_http_referer。我已經閱讀了一些關於模擬對象/方法的內容,但並不完全瞭解在這種情況下如何使用它們。

我可能完全誤解了所有這些工作,但任何幫助將不勝感激!

回答

6

問題是測試運行在命令行模式下,當然,當前用戶沒有在那裏進行身份驗證。

有幾種方法可以使它工作。一種選擇是將驗證功能check_admin_referer()或其基礎wp_verify_nonce()存根。但這不是最好的方法,因爲那裏的測試具有集成的風格,而stubbing更像是單元測試的一種方法。

一個很好的解決方案是驗證用戶以使測試通過。你可以這樣做比較容易像這樣:

public function testValidateSettings() { 
    $_REQUEST['security'] = wp_create_nonce($this->plugin_admin->plugin_name); 

    $this->assertTrue($this->plugin_admin->sc_validate_settings()); 
} 

我不相信會工作,因爲它可能是私有財產。所以,你可以把它當作一個硬編碼字符串:

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連接到它 - 這將幫助您逐步瀏覽代碼並查看哪些功能無法按預期工作。這比盲目地與所有這些偶然事件,HTTP引用者等等一起掙扎更好。


注意

的WP代碼是非常可悲的。全局名稱空間中的函數列表很大,沒有OOP,沒有完整的請求處理週期(例如,意外的die()) - 真的很讓人沮喪,因爲它擴展了代碼庫和測試真的很難。

所以要更多的戰鬥與代碼:)

+0

喜@安德烈 - tserkus,感謝您抽出寶貴的時間提供了詳盡的解答和上下文準備。有效!我需要按照您的建議將插件名稱作爲硬編碼字符串傳遞。好的提示也包含在setUp()中,以便可愛!再次感謝 - 我將準備與WP代碼的未來戰鬥! –

+0

很高興幫助,@EdPatrick –

+0

謝謝,@AndreyTserkus。這個答案也對我最有幫助。我無法得到$ _REQUEST方面的工作,但發現如果我設置當前用戶,'wp_verify_nonce'可以工作。寫了一篇短文,可能會幫助其他人測試WordPress。 [wp_verify_nonce和PHPUnit](http://jhtechservices.com/wp_verify_nonce-and-phpunit-testing/) – jer0dh

相關問題