2016-04-15 120 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