Замена конструкций exit/die в unit-тестах

Замена конструкций exit/die в unit-тестах

Если в коде вы используете die/exit то PHPUnit прекратит работу в этот момент. Для этого нам необходимо заменить конструкцию exit или die. Но это сделать сложно т.к. Functions Mocker с данным не справляется.

Пример:

class Duck { public function last_words() {die( 'I\'ll be back');} }

Меняем класс следующий образом:

class Duck { public function last_words() {return $this->die( 'I\'ll be back');}/** * @codeCoverageIgnore */protected function die( $message = '') {return die( $message);} }

Добавляем к способу die() аннотацию @codeCoverageIgnore, чтобы не учитывать при вычислении покрытия тестов

Вместо реального объекта создаем частичного двойника. Далее разрешаем вызов защищенных способов и делаем заглушку для способа die():

use PHPUnit\Framework\TestCase;class Test_Duck extends TestCase { public function test_last_words() {$duck = \Mockery::mock( Duck::class)->makePartial();$duck->shouldAllowMockingProtectedMethods();$duck->shouldReceive( 'die')->with( 'I\'ll be back')->once()->andReturnArg( 0);$this->assertSame( 'I\'ll be back', $duck->last_words());}}

Это нам может понадобиться после использования редиректов в WordPress, к примеру wp_safe_redirect:

class Some_Class {public function some_method() {wp_safe_redirect(remove_query_arg([ '_wp_http_referer', '_wpnonce' ],wp_unslash( $_SERVER['REQUEST_URI']) // phpcs:ignore));$this->exit();}/** * @codeCoverageIgnore */protected function exit() {exit;}}

И собственно весь тест для этого кода:

use PHPUnit\Framework\TestCase;use function Brain\Monkey\Functions\expect;class Test_Some_Class extends TestCase {public function test_some_method() {$some_url = '/some-url/';$some_class = \Mockery::mock( \Some_Class::class)->makePartial();$some_class->shouldAllowMockingProtectedMethods();$some_class->shouldReceive( 'exit')->once();$_REQUEST['_wp_http_referer'] = 'some-referer';$_SERVER['REQUEST_URI'] = $some_url;expect( 'wp_safe_redirect')->with( $some_url)->once();expect( 'remove_query_arg')->with([ '_wp_http_referer', '_wpnonce' ],$some_url)->once()->andReturn( $some_url);expect( 'wp_unslash')->with($some_url)->once()->andReturn( $some_url);$some_class->some_method();}}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *