没有不值得去解决的问题,也没有不值得去学习的技术!

When Using Variables in Queries, Lighthouse 5 Automated Tests Fail: Syntax Error: Expected Name, found $

执行命令:./vendor/bin/phpunit .\Modules\ThemeStore\Tests\Functional\GraphQl\OnlineStoreThemeGraphQlApiTest.php 。报错:Failed asserting that an array has the subset Array

1. Reference URL: https://lighthouse-php.com/4/testing/phpunit.html#setup . Use PHPUnit for testing. In Lighthouse, adding automated tests via PHPUnit is easy.

2. Run the GraphQL Query API, response 200. Mainly testing the response of the field: themeAssets. As shown in Figure 1

Run the GraphQL Query API, response 200. Mainly testing the response of the field: themeAssets
Figure 1

3. Edit /Modules/ThemeStore/Tests/Functional/GraphQl/OnlineStoreThemeGraphQlApiTest.php , the code is as follows

PHP
<?php
 
namespace Modules\ThemeStore\Tests\Functional\GraphQl;
 
use Nuwave\Lighthouse\Testing\MakesGraphQLRequests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Nuwave\Lighthouse\Testing\ClearsSchemaCache;
use Tests\CreatesApplication;
 
class OnlineStoreThemeGraphQlApiTest extends BaseTestCase
{
    use CreatesApplication,
        ClearsSchemaCache,
        MakesGraphQLRequests;
 
    public function testGetThemeById(): void
    {
        $response = $this->graphQL('
            {
                query GetThemeById($id: ID!) {
                    onlineStoreTheme(themeId: $id) {
                        id
                        editable
                        createdAt
                        name
                    }
                }
            }
            ',
            [
                'id' => 'vogue',
            ]
        );
 
        $response->assertJson([
            'data' => [
                'onlineStoreTheme' => [
                    'id' => 'vogue'
                ],
            ],
        ]);
    }
 
    protected function setUp(): void
    {
        parent::setUp();
 
        $this->bootClearsSchemaCache();
    }
}

4. Execute the command: ./vendor/bin/phpunit .\Modules\ThemeStore\Tests\Functional\GraphQl\OnlineStoreThemeGraphQlApiTest.php . Error: Failed asserting that an array has the subset Array . As shown in Figure 2

Execute the command: ./vendor/bin/phpunit .\Modules\ThemeStore\Tests\Functional\GraphQl\OnlineStoreThemeGraphQlApiTest.php . Error: Failed asserting that an array has the subset Array
Figure 2
Plaintext

PS E:\wwwroot\object> ./vendor/bin/phpunit .\Modules\ThemeStore\Tests\Functional\GraphQl\OnlineStoreThemeGraphQlApiTest.php

PHPUnit 7.5.20 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 919 ms, Memory: 56.00 MB

There was 1 failure:

1) Modules\ThemeStore\Tests\Functional\GraphQl\OnlineStoreThemeGraphQlApiTest::testGetThemeById
Unable to find JSON:

[{
    "data": {
        "onlineStoreTheme": {
            "id": "vogue"
        }
    }
}]

within response JSON:

[{
    "errors": [
        {
            "message": "Syntax Error: Expected Name, found $",
            "extensions": {
                "category": "graphql"
            },
            "locations": [
                {
                    "line": 3,
                    "column": 36
                }
            ]
        }
    ]
}].


Failed asserting that an array has the subset Array &0 (
    'data' => Array &1 (
        'onlineStoreTheme' => Array &2 (
            'id' => 'vogue'
        )
    )
).
--- Expected
+++ Actual
@@ @@
       ),
     ),
   ),
-  'data' =>
-  array (
-    'onlineStoreTheme' =>
-    array (
-      'id' => 'vogue',
-    ),
-  ),
 )

E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Assert.php:108
E:\wwwroot\object\vendor\laravel\framework\src\Illuminate\Foundation\Testing\TestResponse.php:479
E:\wwwroot\object\Modules\ThemeStore\Tests\Functional\GraphQl\OnlineStoreThemeGraphQlApiTest.php:38
phpvfscomposer://E:\wwwroot\object\vendor\phpunit\phpunit\phpunit:60

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
PS E:\wwwroot\object>


5. The root cause is that the response is inconsistent with the response from the manually sent request. Decided to first write a test case without parameters. /tests/Feature/PostsGraphQlApiTest.php

PHP
<?php
 
namespace Tests\Feature;
 
use Nuwave\Lighthouse\Testing\MakesGraphQLRequests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Nuwave\Lighthouse\Testing\ClearsSchemaCache;
use Tests\CreatesApplication;
use App\Models\Post;
 
class PostsGraphQlApiTest extends BaseTestCase
{
    use CreatesApplication,
        ClearsSchemaCache,
        MakesGraphQLRequests;
 
    public function testQueriesPosts(): void
    {
        $post = Post::factory()->create();
        $response = $this->graphQL('
            {
                posts {
                    id
                    title
                    content
                }
            }
        ');
 
        $response->assertJson([
            'data' => [
                'posts' => [
                    [
                        'id' => $post->id,
                        'title' => $post->title,
                        'content' => $post->content,
                    ]
                ],
            ],
        ]);
    }
 
    protected function setUp(): void
    {
        parent::setUp();
 
        $this->bootClearsSchemaCache();
    }
}

6. Run the test: ./vendor/bin/phpunit .\tests\Feature\PostsGraphQlApiTest.php , error: Failed asserting that an array has the subset Array. However, the response is definitely in a JSON structure, it just did not match the first element. As shown in Figure 3

Run the test: ./vendor/bin/phpunit .\tests\Feature\PostsGraphQlApiTest.php , error: Failed asserting that an array has the subset Array. However, the response is definitely in a JSON structure, it just did not match the first element
Figure 3
Plaintext

            {
                "id": "104",
                "title": "Tenetur id labore dolores aperiam.",
it vel ut corrupti repellat quaerat. Et eos exercitationem voluptatem ut."
            },
            {
                "id": "105",
                "title": "Incidunt nulla libero officia aliquam dolor ut.",
                "content": "Molestiae harum velit numquam atque qui consequatur quam. Et sequi voluptatem sunt. Nemo et quo quod consequuntur. Quis eos consequatur recusandae in doloribus rerum odit odio."
            }
        ]
    }
}].


Failed asserting that an array has the subset Array &0 (
    'data' => Array &1 (
        'posts' => Array &2 (
            0 => Array &3 (
                'id' => 105
                'title' => 'Incidunt nulla libero officia aliquam dolor ut.'
                'content' => 'Molestiae harum velit numquam atque qui consequatur quam. Et sequi voluptatem sunt. Nemo et quo quod consequuntur. Quis eos consequatur recusandae in doloribus rerum odit odio.'
            )
        )
    )
).
--- Expected
+++ Actual

     array (
       0 =>
       array (
-        'id' => 105,
-        'title' => 'Incidunt nulla libero officia aliquam dolor ut.',
-        'content' => 'Molestiae harum velit numquam atque qui consequatur quam. Et sequi voluptatem sunt. Nemo et quo quod consequuntur. Quis eos consequatur recusandae in doloribus rerum odit odio.',
+        'id' => '1',
+        'title' => 'Optio earum deserunt fuga qui quia hic.',
+        'content' => 'Fuga molestiae quis sit quis maiores et. Amet eveniet sint quidem deleniti voluptas necessitatibus. Aut aut voluptatibus ut maiores doloremque eos totam.',
       ),
       1 =>
       array (

E:\wwwroot\lighthouse-tutorial\vendor\laravel\framework\src\Illuminate\Testing\Constraints\ArraySubset.php:85
E:\wwwroot\lighthouse-tutorial\vendor\laravel\framework\src\Illuminate\Testing\Assert.php:40
E:\wwwroot\lighthouse-tutorial\vendor\laravel\framework\src\Illuminate\Testing\AssertableJsonString.php:273
E:\wwwroot\lighthouse-tutorial\vendor\laravel\framework\src\Illuminate\Testing\TestResponse.php:695
E:\wwwroot\lighthouse-tutorial\tests\Feature\PostsGraphQlApiTest.php:36
phpvfscomposer://E:\wwwroot\lighthouse-tutorial\vendor\phpunit\phpunit\phpunit:97

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

7. Get the last key-value of the $posts array, and then the match succeeds. The test run passes. As shown in Figure 4

Get the last key-value of the $posts array, and then the match succeeds. The test run passes
Figure 4
PHP
<?php
 
namespace Tests\Feature;
 
use Nuwave\Lighthouse\Testing\MakesGraphQLRequests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Nuwave\Lighthouse\Testing\ClearsSchemaCache;
use Tests\CreatesApplication;
use App\Models\Post;
 
class PostsGraphQlApiTest extends BaseTestCase
{
    use CreatesApplication,
        ClearsSchemaCache,
        MakesGraphQLRequests;
 
    public function testQueriesPosts(): void
    {
        $post = Post::factory()->create();
        $response = $this->graphQL('
            {
                posts {
                    id
                    title
                    content
                }
            }
        ');
 
        $responsePosts = $response->json("data.posts");
        $lastKey = array_key_last($responsePosts);
 
        $response->assertJson([
            'data' => [
                'posts' => [
                    $lastKey => [
                        'id' => $post->id,
                        'title' => $post->title,
                        'content' => $post->content,
                    ]
                ],
            ],
        ]);
    }
 
    protected function setUp(): void
    {
        parent::setUp();
 
        $this->bootClearsSchemaCache();
    }
}
Plaintext

PS E:\wwwroot\lighthouse-tutorial> ./vendor/bin/phpunit .\tests\Feature\PostsGraphQlApiTest.php
PHPUnit 9.5.11 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.434, Memory: 38.00 MB

OK (1 test, 1 assertion)
PS E:\wwwroot\lighthouse-tutorial>

8. Print the response object.

Plaintext

PS E:\wwwroot\lighthouse-tutorial> ./vendor/bin/phpunit .\tests\Feature\UsersGraphQlApiTest.php
PHPUnit 9.5.11 by Sebastian Bergmann and contributors.

Illuminate\Testing\TestResponse Object
(
    [baseResponse] => Illuminate\Http\Response Object
        (
            [headers] => Symfony\Component\HttpFoundation\ResponseHeaderBag Object
                (
                    [computedCacheControl:protected] => Array
                        (
                            [no-cache] => 1
                            [private] => 1
                        )

                    [cookies:protected] => Array
                        (
                        )

                    [headerNames:protected] => Array
                        (
                            [cache-control] => Cache-Control
                            [date] => Date
                            [content-type] => Content-Type
                        )

                    [headers:protected] => Array
                        (
                            [cache-control] => Array
                                (
                                    [0] => no-cache, private
                                )

                            [date] => Array
                                (
                                    [0] => Thu, 20 Jan 2022 06:33:46 GMT
                                )

                            [content-type] => Array
                                (
                                    [0] => application/json
                                )

                        )

                    [cacheControl:protected] => Array
                        (
                        )

                )

            [content:protected] => {"errors":[{"message":"Syntax Error: Expected Name, found $","extensions":{"category":"graphql"},"locations":[{"line":3,"column":36}]}]}
            [version:protected] => 1.1
            [statusCode:protected] => 200
            [statusText:protected] => OK
            [charset:protected] =>
            [original] => Array
                (
                    [errors] => Array
                        (
                            [0] => Array
                                (
                                    [message] => Syntax Error: Expected Name, found $
                                    [extensions] => Array
                                        (
                                            [category] => graphql
                                        )

                                    [locations] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [line] => 3
                                                    [column] => 36
                                                )

                                        )

                                )

                        )

                )

            [exception] =>
        )

    [exceptions:protected] => Illuminate\Testing\LoggedExceptionCollection Object
        (
            [items:protected] => Array
                (
                )

            [escapeWhenCastingToString:protected] =>
        )

    [streamedContent:protected] =>
)
PS E:\wwwroot\lighthouse-tutorial>

9. Finally found that the root cause is an extra layer of curly braces. As shown in Figure 5

Finally found that the root cause is an extra layer of curly braces
Figure 5
PHP

    public function testGetThemeById(): void
    {
        $response = $this->graphQL('
            query GetThemeById($id: ID!) {
                onlineStoreTheme(themeId: $id) {
                    id
                    editable
                    createdAt
                    name
                }
            }
            ',
            [
                'id' => 'vogue',
            ]
        );

        $response->assertJson([
            'data' => [
                'onlineStoreTheme' => [
                    'id' => 'vogue'
                ],
            ],
        ]);
    }

10. Run the test, the test passes. As shown in Figure 6

Run the test, the test passes
Figure 6
Plaintext

PS E:\wwwroot\object> ./vendor/bin/phpunit .\Modules\ThemeStore\Tests\Functional\GraphQl\OnlineStoreThemeGraphQlApiTest.php
PHPUnit 7.5.20 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 1.69 seconds, Memory: 60.00 MB

OK (1 test, 1 assertion)
PS E:\wwwroot\object>

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系