Как стать автором
Обновить

Пространства имён + PHPUnit = 100% покрытие тестами

Время на прочтение2 мин
Количество просмотров3.5K
Давно хотел поделиться с общественностью способом тестировать код, использующий функции для работы с внешней средой: с сокетами, БД, файлами и чем угодно ещё. Сегодня, увидев статью Runkit + PHPUnit = 100% покрытие тестами, решил, что сейчас самое время.
Решение с Runkit красивое, но есть одна проблема — Runkit не распространяется вместе PHP, его надо ставить отдельно. Я же хочу предложить подход, работающий в обычной поставке PHP 5.3+, при одном условии — проект должен использовать пространства имён.

Идея



Идея очень проста и основывается на правилах разрешения имён в PHP: вызванная функция сначала ищется в текущем пространстве имён, и только потом вызывается встроенная функция PHP. Например, в следующем куске кода:

namespace A;
foo();


PHP сначала попытается вызывать A\foo() и только потом foo(). Значит, если мы объявим функцию с именем, скажем, «fsockopen» в пространстве имён проекта, то вначале вызвана будет именно она.

Применение



Предположим, у нас есть вот такой класс:

src/MyClass.php
<?php
namespace MyNS;

class MyClass
{
  public function someMethod()
  {
    $fp = fsockopen('example.org', 123);
  }
}


* This source code was highlighted with Source Code Highlighter.


Чтобы перекрыть функцию fsockopen, создаём в тестах такой вот файл:

tests/helpers.php
<?php
namespace MyNS;

function fsockopen($hostname, $port)
{
  $GLOBALS['fsockopen'] = array($hostname, $port);
}

* This source code was highlighted with Source Code Highlighter.


Теперь можно написать такой тест:

tests/MyClass_Test.php
<?php
namespace MyNS\Tests;
use PHPUnit_Framework_TestCase;
use MyNS\MyClass;

require 'helpers.php';
require '../src/MyClass.php';

class MyClass_Test extends PHPUnit_Framework_TestCase
{
  public function test_someMethod()
  {
    $test = new MyClass();
    $test->someMethod();
    $this->assertEquals(array('example.org', 123), $GLOBALS['fsockopen']);
  }
}


* This source code was highlighted with Source Code Highlighter.


В этом тесте будет вызвана не встроенная fsockopen, а объявленная в helpers.php.

Конечно же вариант с $GLOBALS не единственный возможный, и показан здесь только для простоты. То, что предлагаю — это не готовое решение, а лишь подход, который каждый может приспособить под свои нужды.
Теги:
Хабы:
Всего голосов 35: ↑33 и ↓2+31
Комментарии15

Публикации

Истории

Работа

PHP программист
187 вакансий

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
10 – 11 октября
HR IT & Team Lead конференция «Битва за IT-таланты»
МоскваОнлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Innopolis 2025
Иннополис