2016-08-12 2 views
5

Я только что начал изучать PHPUnit с помощью Wordpress. У меня есть плагин, который получает данные петиции с сайта change.org. Одна из функций класса администратора проверяет параметры из области администрирования Wordpress, а также вызывает `check_admin_referer() как часть этой проверки.Как вы можете PHPUnit проверить функцию 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()); 

    } 

Я попытался установить случайное слово, действие и _wp_http_referer вручную и с помощью wp_nonce_field() через $_POST в тестах/bootstrap.php и в самом тестовом классе. И я немного читал о макетных объектах/методах, но не совсем понимаю, как они могут быть использованы в этом случае.

Возможно, я полностью не понимаю, как все это работает, но любая помощь будет принята с благодарностью!

ответ

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']); 
} 

Я DON» Думаю, вам нужно очистить вновь созданный nonce после тестов, потому что оригинальные тесты 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()); 
} 

Suggestion

Установите Xdebug и подключитесь к нему через вашу IDE - это поможет вам пройти шаг за шагом и посмотреть, что не работает так, как вы ожидали. Это лучше, чем слепо борется со всеми этими несами, http-реферерами и т. Д.


Примечание

код WP довольно печально. Огромный список функций в глобальном пространстве имен, отсутствие ООП, отсутствие полного цикла обработки запросов (например, неожиданный 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

Смежные вопросы