Как проверить метод, который принимает вызываемый в качестве аргумента с PhpUnit и Prophecy

Я использую асинхронный запрос Guzzle и внедрил их в сервис, который я хотел бы проверить сейчас.

Мой метод выглядит следующим образом (псевдо, так что если он не на 100% действителен, извините)

public function getPlayer(string $uiid, array &$player = [])
{
    $options['query'] = ['id' => $uiid];

    $promise = $this->requestAsync('GET', $this->endpoint, $options);
    $promise->then(function (ResponseInterface $response) use (&$player) {
        $player = $response->getBody()->getContents();
    });

    return $players;
}

Теперь я хочу проверить это, но я не знаю, как издеваться над вызываемым, потому что я всегда получаю ошибку

1) tzfrs\PlayerBundle\Tests\Api\Player\PlayerServiceTest::testGetPlayer Prophecy\Exception\InvalidArgumentException: Expected callable or instance of PromiseInterface, but got object.

Вот как у меня это реализовано в настоящее время

/** @var ObjectProphecy|PromiseInterface $response */
$promise = $this->prophesize(PromiseInterface::class);

$promise->then()->will($this->returnCallback(function (ResponseInterface $response) use (&$player){}));

Не сработало И это

$this->returnCallback(function (ResponseInterface $response) use (&$player){})

тоже не работал Та же ошибка И когда просто пытаешься сделать обратный звонок

$promise->then(function(){});

Я получаю ошибку Error: Call to a member function then() on string, даже после ->reveal()сначала обещание. Есть идеи?

2 ответа

У меня была другая идея.

Сделать зависимость, которая сделает то, что вы делаете сейчас в requestAsync(); И затем создайте это макет, который вернет еще один макет обещания.

class PromiseMock
{
    private $response;

    public function __construct(ResponseInterface $response)
    {
        $this->response = $response;
    }

    public function then($callable)
    {
        $callable($this->response);
    }
}

тест выглядит

public function testGetPlayer()
{
    $response = new Response(200, [], "Your test response");
    $promiseMock = new PromiseMock($response);

    $mockDependency = $this->getMockBuilder('YourDependencyClass')
                ->getMock()
                ->expects("requestAsync")->willReturn($promiseMock);

    $service = new YouServiceClass($mockDependency);

    $service->getPlayer("76245914-d56d-4bac-8419-9e409f43e777");
}

И в вашем классе меняется только

$promise = $this->someNameService->requestAsync('GET', $this->endpoint, $options);

Я бы ввел процессор в ваш класс и назвал бы его вызываемым. Проверьте это, остальное вполне очевидно:

public function __construct(Processor $processor) {
    $this->processor = $processor;
}

public function getPlayer(string $uiid, array &$player = [])
{
    $options['query'] = ['id' => $uiid];

    $promise = $this->requestAsync('GET', $this->endpoint, $options);
    $promise->then([$this->processor, "processResponse"]);

    $player = $this->processor->getPlayer();

    return $players;
}

И процессор:

class Processor {

    private $player;        

    public function processResponse (ResponseInterface $response) {
        $this->player = $response->getBody()->getContents();
    }

    public function getPlayer() { return $this->player;}
}
Другие вопросы по тегам