0

I am using PHPUnit and Guzzle to test the REST api, which creates a new record in db, if the username(passed in request parameters) which is not already available in db and it sends response in JSON like below:

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

And if the username is already available in db, then it sends response in JSON like below:

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

This is my PHPUnit testcase to test the above mentioned API along with Guzzle:

  1. This is a setUp function is used to setup the Guzzle client

    public function setUp()
    {
        $this->client = new GuzzleHttp\Client([
            'base_uri' => 'http://localhost/test/'
        ]);
    }
    
  2. And this is the actual test function:

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

Whenever I test this, I get response like this:

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) {
    }
  }
}

But I am not getting the desired response sent back by an API call itself.

If I test my above mentioned API with POSTMAN, it works perfectly and gives back desired responses.

James Z
  • 12,209
  • 10
  • 24
  • 44
Tony Montana
  • 921
  • 18
  • 46
  • 1
    Not an actual answer to your question, but: Unit testing APIs is considered bad practice. Your unit tests should test your classes and code, not their integration. If your API goes down, your unit tests should still go green. You should consider testing this using integration testing tools instead. They are better suited for these kind of tasks. – OptimusCrime Nov 21 '17 at 10:53
  • Thanks @OptimusCrime, but I have seen many examples/posts where they have used PHPUnit and Guzzle to test the APIs. And no one mentioned anything such like you. – Tony Montana Nov 21 '17 at 11:36
  • https://stackoverflow.com/a/7564101/921563 for example – OptimusCrime Nov 21 '17 at 11:58

1 Answers1

2

Have you read the GuzzlePHP documentation? Under 'Quickstart' -> 'Using Responses' it is described that when you want to get the body of the response you'll need to use the getBody() function on the $response.

What you are doing is just dumping the whole request variable, which contains way more information then you'll need for what you want to do.

See Using Responses for an example:

$response = $client->post('your parameters here');
$body = $response->getBody();
echo $body;
Tom Udding
  • 2,264
  • 3
  • 20
  • 30
  • Thanks for replying. But still it doesn't return the desired response. This is what it is returns `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) { } }` – Tony Montana Nov 21 '17 at 11:33
  • 1
    @TonyMontana Are you sure you dont `var_dump` the variable instead of eching it? I can verify that `getBody()` returns the response as text. – OptimusCrime Nov 21 '17 at 11:57
  • Ok, if I use `json_decode($response->getBody())`, I am getting response as expected. But without using `json_decode` I am getting above mentioned response. Thanks @OptimusCrime for your suggestion and also this blog post https://knpuniversity.com/screencast/rest/testing-phpunit – Tony Montana Nov 21 '17 at 12:00
  • Sorry it is `json_decode($response->getBody(), true)` – Tony Montana Nov 21 '17 at 12:07