Почему мой макет PHPUnit клиента Predis не соответствует моим ожиданиям?

Я пытаюсь издеваться над клиентом Predis в тесте PHPUnit. Когда я вызываю метод, который пытался смоделировать, в конце теста PHPUnit сообщает мне, что ожидание не оправдалось.

Вот пример кода, который воспроизводит мою проблему:

class MockRedisTest extends \PHPUnit_Framework_TestCase {
private $mockRedis;

public function testMockRedis() {

    $mockRedis =  $this->getMock('Predis\\Client');

    $mockRedis->expects(  $this->once())
      ->method("exists")
      ->with($this->equalTo("query-key"))
      ->will($this->returnValue(true));

    $mockRedis->exists("query-key");
}

}

И PHPUnit считает, что метод не вызывался:

1) MockRedisTest::testMockRedis Ожидание не выполнено для имени метода, равного при вызове 1 раз. Ожидалось, что метод будет вызван 1 раз, на самом деле он вызывается 0 раз.

Почему? Это потому, что клиент Predis, похоже, использует __call для ответа на вызовы методов, которые соответствуют командам Redis?

ОБНОВЛЕНИЕ: у меня сложилось впечатление, что это как-то связано с методом __call. Изменение кода на это работает:

public function testMockRedis() {

    $mockRedis =  $this->getMock('Predis\\Client');

    $mockRedis->expects(  $this->once())
      ->method("__call")
      ->with("exists", $this->equalTo(array("query-key")))
      ->will($this->returnValue(true));

    $mockRedis->exists("query-key");
}

Хотя не уверен, что я доволен этим. Есть ли лучший способ издеваться над классами, использующими __call для прокси-методов?


person Tom Martin    schedule 18.10.2011    source источник


Ответы (3)


Я думаю, вы можете использовать

$mockRedis =  $this->getMock('Predis\\Client', array('exists'));
// ...

чтобы заставить фиктивный объект узнать о вашей магической функции. Это ограничивает возможности макета методом exists(). Вам нужно будет специально указать все остальные методы, которые нужно высмеивать.

person Stefan Gehrig    schedule 18.10.2011

Если вы хотите имитировать определенный профиль сервера и убедиться, что вы не вызываете методы другой версии сервера, используйте

<?php
$mockRedis = $this->getMock('Predis\\Client', array_keys((new Predis\Profiles\ServerVersion26)->getSupportedCommands()));
person Lars Strojny    schedule 02.08.2012

Для Phpunit 5 используйте

$this->createPartialMock('Predis\\Client', ['exists']);

Чтобы ваш макет знал о методе «существует» (или любой другой родной команде Redis)

person Romain Bigz    schedule 08.11.2016