JSON 响应断言失败 PHP 单元

Posted

技术标签:

【中文标题】JSON 响应断言失败 PHP 单元【英文标题】:JSON Response Assert Fails PHP Unit 【发布时间】:2017-10-23 22:49:21 【问题描述】:

我正在创建一个 Laravel 应用程序并使用 php 单元进行测试。我正在尝试为我的端点编写测试。我有一个端点,它返回数据库中所有客户端的 JSON 响应,如下所示:


data: [
 
   id: 1,
   name: "test",
   password: "p@ssword",
   description: "test client",
   ip: "192.168.0.1",
   created: "2017-05-18T19:16:20+00:00",
   updated: "2017-05-18T19:16:23+00:00"
 ,
 
   id: 2,
   name: "test",
   password: "p@ssword",
   description: "test client 2",
   ip: "192.168.0.2",
   created: "2017-05-22T19:16:20+00:00",
   updated: "2017-05-22T19:16:23+00:00"
  
 ]

然后我创建了一个 ClientControllerTest,它将使用测试数据库和 Faker 检查 JSON 响应。我的ClientControllerTest如下:

<?php

namespace Tests\App\Http\Controllers;

use Tests\TestCase;
use Carbon\Carbon;
use App\Client;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class ClientsControllerTest extends TestCase

    use DatabaseMigrations;

    public function setUp()
    
        parent::setUp();
        Carbon::setTestNow(Carbon::now('UTC'));
    

    public function tearDown()
    
        parent::tearDown();
        Carbon::setTestNow();
    

    /** @test */
    public function index_status_code_should_be_200()
    
        $this->get('api/clients')->assertStatus(200);
    

    /** @test */
    public function index_should_return_a_collection_of_records()
    
        $clients = factory(Client::class, 2)->create();

        $response = $this->json('GET', 'api/clients');

        $response->assertStatus(200);

        $content = json_decode($response->getContent(), true);
        $this->assertArrayHasKey('data', $content);

        foreach ($clients as $client) 
            $response->assertJson([
                "id"            =>  $client->id,
                "name"          =>  $client->name,
                "password"      =>  $client->password,
                "description"   =>  $client->description,
                "ip"            =>  $client->ip,
                "created"       =>  $client->created_at->toIso8601String(),
                "updated"       =>  $client->updated_at->toIso8601String()
            ]);
        
    

但是,当我尝试运行 PHPUnit 时,我收到一个奇怪的错误,似乎断言 $response->assertJSON 失败,即使我可以在错误消息中看到输出?错误信息如下:

1) Tests\App\Http\Controllers\ClientsControllerTest::index_should_return_a_collection_of_records
Unable to find JSON:

[
    "id": 1,
    "name": "Christophe Sporer",
    "password": "VaK~\\g",
    "description": "Saepe nisi accusamus numquam dolores voluptate id.",
    "ip": "195.177.237.184",
    "created": "2017-05-23T19:53:43+00:00",
    "updated": "2017-05-23T19:53:43+00:00"
]

within response JSON:

[
    "data": [
        
            "id": 1,
            "name": "Christophe Sporer",
            "password": "VaK~\\g",
            "description": "Saepe nisi accusamus numquam dolores voluptate id.",
            "ip": "195.177.237.184",
            "created": "2017-05-23T19:53:43+00:00",
            "updated": "2017-05-23T19:53:43+00:00"
        ,
        
            "id": 2,
            "name": "Miss Virginie Johnson",
            "password": "e1\"~q\\*oSe^",
            "description": "Nihil earum quia praesentium iste nihil nulla qui occaecati non et perspiciatis.",
            "ip": "110.125.57.83",
            "created": "2017-05-23T19:53:43+00:00",
            "updated": "2017-05-23T19:53:43+00:00"
        
    ]
].


Failed asserting that an array has the subset Array &0 (
    'id' => 1
    'name' => 'Christophe Sporer'
    'password' => 'VaK~\g'
    'description' => 'Saepe nisi accusamus numquam dolores voluptate id.'
    'ip' => '195.177.237.184'
    'created' => '2017-05-23T19:53:43+00:00'
    'updated' => '2017-05-23T19:53:43+00:00'
).

我有点困惑为什么这会失败,因为 PHPUnit 似乎没有提供更多信息,我确实断言对 api/clients 的请求有效并返回了 200,所以我知道响应是准确的。

感谢任何帮助,谢谢!

【问题讨论】:

【参考方案1】:

您的响应数据格式为 'data' =&gt; [ ... ] ,其中您想要的子集位于[ ... ] 内。但是,您要求查找结构 'id': ..., ... ,它在顶层不存在。您需要在 $response 的数据成员中声明 JSON。

您可以改为使用:

assertJson([ 'data' => [ "id" => $client->id, ... ] ])

【讨论】:

作为旁注,你也可以使用 Laravel 5.4 的 assertJsonFragment assertJsonFragment 更有帮助

以上是关于JSON 响应断言失败 PHP 单元的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 单元测试断言函数总是失败

Jmeter JSON路径断言

jmeter断言,结果报告--6(响应断言和JSON断言,聚合报告,查看结果树)常见状态吗的排查方式

Jmeter JSON断言和响应断言的区别是什么?

jmter添加断言

2使用断言(json assertion)