Как мне тестировать код сокета с помощью PHPUnit? - PullRequest
8 голосов
/ 04 февраля 2012

В настоящее время у меня есть класс Socket, который по сути является просто классом-оболочкой OO для функций socket_* PHP:

class Socket {
    public function __construct(...) {
        $this->_resource = socket_create(...);
    }

    public function send($data) {
        socket_send($this->_resource, $data, ...);
    }

    ...
}

Не думаю, что смогу издеваться над ресурсом сокета, так как использую функции сокетов PHP, поэтому сейчас я застрял в том, как надежно выполнить модульное тестирование этого класса.

1 Ответ

16 голосов
/ 04 февраля 2012

Вы, похоже, упускаете маленький кусочек мышления модульного теста.

Ваша проблема легко решается путем создания объекта-заглушки.Странно, я даю этот ответ снова и снова, поэтому многие люди в основном его пропускают.

Потому что я вижу столько путаницы относительно различий между заглушками и насмешками,позвольте мне также изложить это здесь ...

  • Макет - это класс, который расширяет другой класс , что тест является напрямую зависит, чтобы изменить поведение этого класса , чтобы упростить тестирование .
  • Заглушка - это класс, который * реализует API или интерфейс ** что тест не может легко тестировать непосредственно сам по себе, чтобы сделал возможным тестирование .

^ - Это самое ясное описание двух, которые я когда-либо читал;Я должен разместить его на своем сайте.

Сокеты имеют эту замечательную функцию, с помощью которой вы можете связываться с портом 0 для целей тестирования (серьезно, это называется «эфемерный порт»).:

class ListeningServerStub
{
    protected $client;

    public function listen()
    {
        $sock = socket_create(AF_INET, SOCK_STREAM, 0);

        // Bind the socket to an address/port
        socket_bind($sock, 'localhost', 0) or throw new RuntimeException('Could not bind to address');

        // Start listening for connections
        socket_listen($sock);

        // Accept incoming requests and handle them as child processes.
        $this->client = socket_accept($sock);
    }

    public function read()
    {
        // Read the input from the client – 1024 bytes
        $input = socket_read($this->client, 1024);
        return $input;
    }
}

Создайте этот объект и установите его для прослушивания в setUp() вашего теста, а также прекратите прослушивание и уничтожьте его в tearDown().Затем, в вашем тесте, подключитесь к вашему поддельному серверу, получите данные обратно с помощью функции read() и протестируйте это.

Если это вам очень поможет, подумайте над тем, чтобы дать мне награду за мысли за пределамитрадиционная коробка; -)

...