2016-04-15 77 views
1

我目前正在爲我的API編寫一些測試,我很想知道是否有更好的方法來處理這個問題,因爲我覺得這是做事的「黑客」方式。集成測試JSON API響應

代碼下面的例子:

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

我不知道是否有更好的東西我可以做測試我的API的JSON API規格相匹配。開導我!我很確定PHPUnit不是我的答案。

回答

3

首先,我不認爲以編程方式聲明某個JSON結構,因爲您現在正在執行的操作本身就是不好的做法。但是,我確實同意在某些時候可能會很麻煩並且可以更有效地解決。

我有同樣的問題,前一段時間,並最終編寫使用JSON schemataJSONPath expressions用於驗證一個給定的JSON文件的結構的新的作曲包(helmich/phpunit-json-assert,這是available as open source)。

使用JSON模式,你的榜樣測試用例可以寫成如下:

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']] 
      ] 
     ] 
    ]); 
} 

雖然有點更詳細的(至於行 - 的代碼),我體會到JSON模式對於這個用例,由於它是一個被廣泛採用的標準,並且(imho)更容易閱讀那些陳述的牆壁。您還可以將單元測試中的模式定義提取到單獨的文件中,並使用它們做其他事情;例如自動生成文檔(Swagger也使用JSON模式的子集)或運行時驗證。

+0

非常感謝。我一定會在本週看你的包裝。我覺得我做的是正確的事情,只是認爲它可以更整潔。你的答案肯定有幫助!再次感謝。 – BennyC