This package provides some tools to help you test GraphQL APIs developed using Lighthouse. The library is targeted at Lighthouse and will not work with other libraries.
You can install this library with composer.
composer require --dev knevelina/laravel-lighthouse-test
That's it, the package is now installed. It will do nothing yet until you add the traits to your tests. Alternatively, you can use the traits in your base TestCase
to be able to use the functionality everywhere.
This feature requires the BuildsGraphQLQueries
trait:
<?php
namespace Tests\Feature;
use Knevelina\LighthouseTest\Traits\BuildsGraphQLQueries;
use Tests\TestCase;
class FeatureTest extends TestCase
{
use BuildsGraphQLQueries;
}
Now you can create queries and mutations programmatically using the makeGraphQLQuery
and makeGraphQLMutation
methods. They both take three arguments:
string $field
: The name of the member ofQuery
orMutation
you wish to query or mutate.array $arguments
: Arguments to pass to the query or mutation.array $selection
: Fields you wish to select from the result.
If $selection
is null
, $arguments
is considered to contain the selection. In other words, the $arguments
argument is optional.
The methods both return an instance of Knevelina\LighthouseTest\Schema\GraphQLQuery
. You can now use this instance to run various tests against your API.
What makes this feature useful, is the fact that you can now create "template" queries and mutations, just like the users of your API will do, where you can test the query with different variables. Simply substitute the raw value in an argument with an instance of the Variable
class.
Consider an application with the following, simple GraphQL schema:
type Reverse {
result: String!
}
type Query {
"Return the reverse of str."
reverse(str: String!): Reverse!
}
<?php
namespace Tests\Feature;
use Knevelina\LighthouseTest\Traits\BuildsGraphQLQueries;
use Tests\TestCase;
class FeatureTest extends TestCase
{
use BuildsGraphQLQueries;
public function testQuery()
{
$query = $this->makeGraphQLQuery('reverse', ['str' => $this->makeVariable('str', 'String!'))], []);
$response = $this->postGraphQL($query->getQuery(['str' => 'hello']));
$this->assertEquals('olleh', $response->json('data.reverse.result'));
$response = $this->postGraphQL($query->getQuery(['str' => 'world']));
$this->assertEquals('dlrow', $response->json('data.reverse.result'));
}
}
The MakesGraphQLQueries
trait introduces the makeVariable(string $name, string $type): Variable
method, which introduces a variable to your query. The variable will automatically be declared in the root query
or mutation
as an argument when constructing the query:
$query = $this->makeGraphQLQuery('hero', ['name' => $this->makeVariable('name', 'String!'), ['id']);
$query->getQuery(['name' => 'John Doe']);
query($name: String!) {
hero(name: $name) {
id
}
}
The getQuery
method also supports instances of Illuminate\Http\UploadedFile
, which means you can use Laravel's fake uploaded files to test fields using the multipart file upload specification.
$query->getQuery([
'file' => UploadedFile::fake()->image('avatar.jpg')
]);
This library is able to automatically format numbers, strings, files and (associative) arrays. Unfortunately, without a custom type, it is not possible to recognize the difference between regular strings and enums. Thus, when using enums, use the Enum
wrapper object. You can create one with the makeEnum(string $name): Enum
method.
$this->getMutation('setStatus', [
'status' => $this->makeEnum('FINISHED')
]);
The query can be sent using Lighthouse's postGraphQL
method, and thus you can refer to Lighthouse's documentation on assertions to use the queries to make assertions.
Laravel's default TestResponse
is not really suited for asserting properties of GraphQL responses. The InterpretsGraphQLResponses
trait aims to help with that.
<?php
namespace Tests\Feature;
use Knevelina\LighthouseTest\Traits\InterpretsGraphQLResponses;
use Tests\TestCase;
class FeatureTest extends TestCase
{
use InterpretsGraphQLResponses;
}
You may now use the following assertions:
$response = $this->graphQL($query);
// Assert any error was returned.
$this->assertHasGraphQLError($response);
// Assert a certain error message was returned.
$this->assertHasGraphQLErrorMessage($response, 'Unauthenticated.');
// Assert no error has returned.
$this->assertHasNoGraphQLError($response);