2017-03-07 66 views
10

我正在创建一个单元测试,并且想要测试响应中返回的JSON结构。我知道TestResponse提供了一种方法assertJsonStructure来匹配您的JSON响应的结构。但由于某种原因,我无法将$structure映射到我的响应中,导致测试失败。让我分享所需的片段。在PhpUnit测试中匹配JsonStructure - Laravel 5.4

端点响应

{ 
    "status": true, 
    "message": "", 
    "data": [ 
     { 
      "id": 2, 
      "name": "Shanelle Goodwin", 
      "email": "[email protected]", 
      "created_at": "2017-03-05 16:12:49", 
      "updated_at": "2017-03-05 16:12:49", 
      "user_id": 1 
     } 
    ] 
} 

测试功能

public function testEndpoint(){ 

    $response = $this->get('/api/manufacturer/read', [], $this->headers); 
    $response->assertStatus(200); 
    $response->assertJsonStructure([ 
    'status', 
    'message', 
    'data' => [ 
     { 
     'id', 
     'name', 
     'email', 
     'created_at', 
     'updated_at', 
     'user_id' 
     } 
    ] 
    ]); 
    var_dump("'/api/manufacturer/read' => Test Endpoint"); 
} 

,可以通过在data阵列中的多个节点所以这就是为什么我想提结构数组,但似乎它不” t地图正确。任何帮助将不胜感激:-)

回答

13

幸运的是,使用不同的选项打我已经解决了这个问题。如果我们要匹配数组中的嵌套对象,那么'*'是期望的关键。我们可以在这里看到参考。

Source: TestResponse - Line # 363

我已经这样设置结构array of objects`

$response->assertJsonStructure([ 
    'status', 
    'message', 
    'data' => [ 
     '*' => [ 
     'id', 
     'name', 
     'email', 
     'created_at', 
     'updated_at', 
     'user_id' 
     ] 
    ] 
    ]); 

如果你想匹配只是一个单一的对象

$response->assertJsonStructure([ 
    'status', 
    'message', 
    'data' => [ 
     [ 
     'id', 
     'name', 
     'email', 
     'created_at', 
     'updated_at', 
     'user_id' 
     ] 
    ] 
    ]); 
+1

非常有用!应该在官方文档中。感谢您为我们钓鱼。 –

+1

我的英雄,谢谢 –

+0

[代码已移动](https://github.com/laravel/framework/blob/5.4/src/Illuminate/Foundation/Testing/TestResponse.php#L363) –

1

我认为你应该使用:

$response->assertJsonStructure([ 
    'status', 
    'message', 
    'data' => [ 
     [ // change here 
     'id', 
     'name', 
     'email', 
     'created_at', 
     'updated_at', 
     'user_id' 
     ] // change here 
    ] 
    ]); 
+0

你是正确的,但一个匹配'data'数组中的单个对象。我解决了这个问题并在下面发布。谢谢 –