PHPUnit - Guzzle: вызовы API не возвращают желаемый ответ

Я использую PHPUnit и Guzzle для тестирования API REST, который создает новую запись в БД, если username (передается в параметрах request), который еще не доступен в БД, и отправляет ответ в JSON, как показано ниже:

{
    "success": true,
    "id": "<unique_ID>"
}

И если username уже доступен в БД, то он отправляет ответ в формате JSON, как показано ниже:

{
    "success": false,
    "error": "username is already available"
}

Это мой тестовый пример PHPUnit для тестирования вышеупомянутого API вместе с Guzzle:

  1. Это функция setUp, используемая для настройки клиента Guzzle.

    public function setUp()
    {
        $this->client = new GuzzleHttp\Client([
            'base_uri' => 'http://localhost/test/'
        ]);
    }
    
  2. И это фактическая тестовая функция:

    public function testActualResult()
    {
        $response = $this->client->post('service.php', [
            'json' => [
                'operation' => 'create_user',
                'user_name' => 'testUser1'            
            ]
        ]);
    
        var_dump($response);
    }
    

Всякий раз, когда я проверяю это, я получаю такой ответ:

class GuzzleHttp\Psr7\Response#99 (6) {
  private $reasonPhrase =>
  string(2) "OK"
  private $statusCode =>
  int(200)
  private $headers =>
  array(5) {
    'Date' =>
    array(1) {
      [0] =>
      string(29) "Tue, 21 Nov 2017 10:27:22 GMT"
    }
    'Server' =>
    array(1) {
      [0] =>
      string(47) "Apache/2.4.26 (Win32) OpenSSL/1.0.2l PHP/5.6.31"
    }
    'X-Powered-By' =>
    array(1) {
      [0] =>
      string(10) "PHP/5.6.31"
    }
    'Content-Length' =>
    array(1) {
      [0] =>
      string(4) "1357"
    }
    'Content-Type' =>
    array(1) {
      [0] =>
      string(16) "application/json"
    }
  }
  private $headerNames =>
  array(5) {
    'date' =>
    string(4) "Date"
    'server' =>
    string(6) "Server"
    'x-powered-by' =>
    string(12) "X-Powered-By"
    'content-length' =>
    string(14) "Content-Length"
    'content-type' =>
    string(12) "Content-Type"
  }
  private $protocol =>
  string(3) "1.1"
  private $stream =>
  class GuzzleHttp\Psr7\Stream#86 (7) {
    private $stream =>
    resource(408) of type (stream)
    private $size =>
    NULL
    private $seekable =>
    bool(true)
    private $readable =>
    bool(true)
    private $writable =>
    bool(true)
    private $uri =>
    string(10) "php://temp"
    private $customMetadata =>
    array(0) {
    }
  }
}

Но я не получаю желаемого ответа, отправленного самим вызовом API.

Если я протестирую вышеупомянутый API с помощью POSTMAN, он отлично работает и возвращает желаемые ответы.


person Tony Montana    schedule 21.11.2017    source источник
comment
Не фактический ответ на ваш вопрос, но: API-интерфейсы модульного тестирования считаются плохой практикой. Ваши модульные тесты должны проверять ваши классы и код, а не их интеграцию. Если ваш API выйдет из строя, ваши модульные тесты все равно должны стать зелеными. Вместо этого вам следует рассмотреть возможность тестирования с помощью инструментов интеграционного тестирования. Они лучше подходят для таких задач.   -  person OptimusCrime    schedule 21.11.2017
comment
Спасибо @OptimusCrime, но я видел много примеров/сообщений, в которых они использовали PHPUnit и Guzzle для тестирования API. И никто не упомянул ничего подобного, как вы.   -  person Tony Montana    schedule 21.11.2017
comment
stackoverflow.com/a/7564101/921563 например   -  person OptimusCrime    schedule 21.11.2017


Ответы (1)


Вы читали документацию по GuzzlePHP? В разделе «Быстрый старт» -> «Использование ответов» описано, что если вы хотите получить тело ответа, вам нужно будет использовать функцию getBody() в файле $response.

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

См. пример Использование ответов:

$response = $client->post('your parameters here');
$body = $response->getBody();
echo $body;
person Tom Udding    schedule 21.11.2017
comment
Спасибо за ответ. Но все же он не возвращает желаемого ответа. Вот что он возвращает class GuzzleHttp\Psr7\Stream#86 (7) { private $stream => resource(408) of type (stream) private $size => NULL private $seekable => bool(true) private $readable => bool(true) private $writable => bool(true) private $uri => string(10) "php://temp" private $customMetadata => array(0) { } } - person Tony Montana; 21.11.2017
comment
@TonyMontana Вы уверены, что не var_dump переменную вместо того, чтобы вычертить ее? Я могу убедиться, что getBody() возвращает ответ в виде текста. - person OptimusCrime; 21.11.2017
comment
Хорошо, если я использую json_decode($response->getBody()), я получаю ответ, как и ожидалось. Но без использования json_decode я получаю вышеупомянутый ответ. Спасибо @OptimusCrime за ваше предложение, а также за этот пост в блоге knpuniversity.com/screencast/rest/testing-phpunit. - person Tony Montana; 21.11.2017
comment
Извините, это json_decode($response->getBody(), true) - person Tony Montana; 21.11.2017