集成测试JSON API响应

时间:2016-04-15 10:17:31

标签: php json phpunit integration-testing silex

我目前正在为我的API编写一些测试,我很想知道是否有更好的方法来解决这个问题,因为我觉得这是“hacky”做事方式。

下面的代码示例:

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

    $client = $this->createClient();
    $client->request("GET", "/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不是我的答案。

1 个答案:

答案 0 :(得分:3)

首先,我不相信你现在正在以编程方式断言某个JSON结构本身就是不好的做法。但是,我确实同意它可能在某些时候变得麻烦,并且可以更有效地解决。

前一段时间我遇到了同样的问题,最后编写了一个新的Composer包(helmich/phpunit-json-assertavailable as open source),使用JSON schemataJSONPath expressions进行验证给定JSON文档的结构。

使用JSON模式,您的示例测试用例可以编写如下:

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

    $client = $this->createClient();
    $client->request("GET", "/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)更容易阅读{{ {1}}陈述。您还可以将单元测试中的模式定义提取到单独的文件中,并使用它们执行其他操作;例如,自动生成文档(Swagger也使用JSON模式的子集)或运行时验证。