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

Click here to view original web page at www.kobzarev.com
Обложка к записи Замена конструкций exit/die в unit-тестах

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

Пример:

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

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

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

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

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

0102030405060708091011121314151617use 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:

0102030405060708091011121314151617181920class 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;}}

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

010809101112131415161718192021222324252627282930313233343536use 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();}}

Источник: WP Punk.

Смотрите также