PankovAlxndr
@PankovAlxndr
Fullstack web developer

Почему не работает Mock объект в PHPUnit?

Здравствуйте, у меня есть метод, хочу покрыть его тестами (метод внутри класса Api.php)
/**
     * @param RequestInterface    $request
     * @param SerializerInterface $serializer
     *
     * @return ResponseInterface
     * @throws ClientExceptionInterface If an error happens while processing the request.
     * @throws RuntimeException RuntimeException for the Serializer
     */
    public function request(RequestInterface $request, SerializerInterface $serializer): ResponseInterface
    {
        $request->setAuth($this->token);
        $body = $serializer->serialize($request, 'xml');  // тут большой xml с кучей вложенности
        $psrRequest = new \Nyholm\Psr7\Request('POST', $this->url, [], $body);  // вот тут ошибка в тесте
        return $this->client->sendRequest($psrRequest);
    }

Пишу такой тест
public function testRequest()
    {
        $clientMock = $this->createMock(ClientInterface::class);
        $requestMock = $this->createMock(RequestInterface::class); // клиентский запрос
        $serializerMock = $this->createMock(SerializerInterface::class);

        $requestMock->expects($this->once()) 
            ->method('setAuth')
            ->with($this->equalTo('my_token'));

        $serializerMock->expects($this->once()) // сериализация клиентского запроса
            ->method('serialize')
            ->with($this->identicalTo($requestMock), 'xml')
            ->willReturn('<?xml version="1.0" encoding="UTF-8"?>');

        $clientMock->expects($this->once()) // класс клиента создает PSR реквест и отправляет его, получая PSR респонс
            ->method('sendRequest')
            ->with($this->createMock(\Nyholm\Psr7\Request::class)) // вот тут все ломается, почему не мокается как выше?
            ->willReturn($this->createMock(ResponseInterface::class));

        $api = new Api($clientMock, 'my_token', 'url'); // создаю оригинал API и передаю туда мок клиента
        $api->request($requestMock, $serializerMock); // пытаюсь сделать запрос, передавая все зависимости как моки
    }

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

Expectation failed for method name is "sendRequest" when invoked 1 time(s)
Parameter 0 for invocation Psr\Http\Client\ClientInterface::sendRequest(Nyholm\Psr7\Request Object (...)): Psr\Http\Message\ResponseInterface does not match expected value.
Nyholm\Psr7\Request Object &0000000070c70e970000000004e60306 (


Почему так? Он мне говорит что метод sendRequest внутри моего тестируемого метода вызывается НЕ С ТАКИМ ПАРАМЕТРОМ, с которым ты ожидаешь в тесте, а как так, почему мок не сработал? если убрать ожидание
->with($this->createMock(\Nyholm\Psr7\Request::class)
, тогда тест проходит, но такой тест мне не нравится, я хочу контролировать что именно передается в метод sendRequest
  • Вопрос задан
  • 76 просмотров
Пригласить эксперта
Ответы на вопрос 1
В методе request третьей строкой создаётся экземпляр объекта Request, и далее именно он передается в метод ClientInterface::sendRequest. А вы в тесте ожидаете что туда будет передан мок:
->with($this->createMock(\Nyholm\Psr7\Request::class))
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы