#php #mocking #redis #phpunit #predis
#php #издевательство #redis #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");
}
Не уверен, что я доволен этим, хотя. Есть ли лучший способ имитировать классы, которые используют __вызов прокси-методов?
Ответ №1:
Я думаю, вы можете использовать
$mockRedis = $this->getMock('Predis\Client', array('exists'));
// ...
чтобы заставить макет объекта узнать о вашей волшебной функции. Однако это ограничивает возможности mock для метода exists()
. Вам придется специально включить все другие методы, которые будут издеваться.
Ответ №2:
Если вы хотите создать макет определенного профиля сервера и убедиться, что вы не вызываете методы другой версии сервера, используйте
<?php
$mockRedis = $this->getMock('Predis\Client', array_keys((new PredisProfilesServerVersion26)->getSupportedCommands()));
Ответ №3:
Для Phpunit 5 используйте
$this->createPartialMock('Predis\Client', ['exists']);
Чтобы ваш макет знал о методе «exists» (или любой другой собственной команде redis)