Search code examples
phplaravelgraphqllaravel-lighthouse

Laravel Lighthouse GraphQL unit tests: "Variable not defined"


I know my question title might not be the most informative, so please let me know if I can improve it somehow :).

I'm trying to figure out how to pass GraphQL variables in a PHP unit test without writing them inline in the query.

Here is a demo code. I cannot give the exact real source code as it belongs to a customer project. I hope that this simplified version will be able to show the problem.

class MyGraphQLTest extends Illuminate\Foundation\Testing\TestCase
{
    use Tests\CreatesApplication;
    use \Nuwave\Lighthouse\Testing\MakesGraphQLRequests;

    public function testSomething()
    {
        // Query an article with a specific id defined in this variable
        $this->graphQL(/** @lang GraphQL */ '
                {
                    article(id: $test_id) {
                        id,
                        name
                    }
                }',
            [
                'test_id' => 5, // Does not work, the variable is not passed for some strange reason.
            ]
        )->assertJson([
            'data' => [
                'article' => [ // We should receive an article with id 5 and title 'Test Article'
                    'id' => 5,
                    'name' => 'Test Article',
                ]
            ]
        ]);
    }
}

According to this Lighthouse: Testing with PHPUnit guide, variables should be able to be passed as an array as a second argument to the ->graphQL() method.

When I run the test with php vendor/bin/phpunit, I get the following error response:

[{
    "errors": [
        {
            "message": "Variable \"$test_id\" is not defined.",
            "extensions": {
                "category": "graphql"
            },
            "locations": *removed as not needed in this question*
        }
    ]
}].

Lighthouse is the newest version: 4.15.0

Thank you for your support! :)


Solution

  • There is something you forgot in your GraphQL query. You must have an query wrapper that will receive parameters and then pass to your query with variables defined. Like this:

    query Articles($test_id: Int! /* or ID! if you prefer */){
        {
            article(id: $test_id) {
                id,
                name
            }
        }
    }
    

    If you are using multiple parameters, consider creating an Input in your GraphQL Server and then in your query you can simply refer to your Input.

    // Consider following Input in your server
    input ArticleSearch {
        article_category: String!
        article_rate: Int!
    }
    
    // you can then
    query Articles($input: ArticleSearch){
        {
            article(input: $input) {
                id,
                name
            }
        }
    }