如何使用PhpUnit和Prophecy

时间:2016-09-16 10:36:55

标签: php promise phpunit guzzle 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 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

我会给你的班级注入一个处理器并调用它是可调用的。看看,其余的很明显:

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;}
}