2016-04-15 11 views
1

Ich schreibe gerade einige Tests für meine API, und ich bin neugierig zu wissen, ob es einen besseren Weg gibt, damit umzugehen, da ich denke, dass dies der "hacky" Weg ist, Dinge zu tun .Integration Testing JSON API Antwort

Code-Beispiel unten:

public function testListingOfAllUsers() 
{ 
    $users = $this->createUsers(); 

    $client = $this->createClient(); 
    $client->request("GET", "https://stackoverflow.com/users/"); 

    $response = $client->getResponse(); 
    $content = $response->getContent(); 
    $decodedContent = json_decode($content); 

    $this->assertTrue($response->isOk()); 
    $this->assertInternalType("array", $decodedContent->data); 
    $this->assertCount(count($users), $decodedContent->data); 

    foreach ($decodedContent->data as $data) { 
     $this->assertObjectHasAttribute("attributes", $data); 
     $this->assertEquals("users", $data->type); 
    } 
} 

Ich frage mich, ob etwas besser da ist kann ich meine API testen Sie die JSON-API-Spezifikation entspricht. Kläre mich auf! Ich bin ziemlich sicher, dass PHPUnit hier nicht meine Antwort ist.

Antwort

3

Erstens glaube ich nicht, dass das Programmatische behauptet eine bestimmte JSON-Struktur, wie Sie gerade tun, ist schlechte Praxis per se. Ich stimme jedoch zu, dass es irgendwann beschwerlich werden könnte und effizienter gelöst werden könnte.

Ich hatte das gleiche Problem vor einer Weile und am Ende ein neues Composer-Paket zu schreiben (helmich/phpunit-json-assert, die available as open source ist), die JSON schemata und JSONPath expressions zur Überprüfung der Struktur eines gegebenen JSON-Dokuments verwendet.

ein JSON-Schema verwenden, Ihrem Beispiel Testfall geschrieben werden könnte wie folgt:

public function testListingOfAllUsers() 
{ 
    $users = $this->createUsers(); 

    $client = $this->createClient(); 
    $client->request("GET", "https://stackoverflow.com/users/"); 

    $response = $client->getResponse(); 
    $content = $response->getContent(); 
    $decodedContent = json_decode($content); 

    $this->assertTrue($response->isOk()); 
    $this->assertJsonDocumentMatchesSchema($decodedContent, [ 
     'type' => 'array', 
     'items' => [ 
      'type'  => 'object', 
      'required' => ['attributes', 'type'], 
      'properties' => [ 
       'attributes' => ['type' => 'object'], 
       'type'  => ['type' => 'string', 'enum' => ['user']] 
      ] 
     ] 
    ]); 
} 

Obwohl es ein wenig ausführlicher (in Bezug auf die Linien-of-Code), ich bin gekommen, JSON Schemata zu schätzen für diesen Anwendungsfall, da es ein weit verbreiteter Standard ist und (imho) einfacher zu lesen ist, dass eine Wand von assert* Aussagen. Sie könnten auch die Schemadefinitionen aus Ihren Komponententests in separate Dateien extrahieren und andere Dinge mit ihnen tun; zum Beispiel die automatisch generierende Dokumentation (Swagger verwendet auch eine Teilmenge des JSON-Schemas) oder die Laufzeitvalidierung.

+0

Sehr geschätzt. Ich werde diese Woche definitiv auf dein Paket schauen. Ich fühlte, dass ich das Richtige tat, dachte nur, es könnte aufgeräumter sein. Deine Antwort hat definitiv geholfen! Danke noch einmal. – BennyC