Skip to content

Latest commit

 

History

History
129 lines (106 loc) · 4.26 KB

16.graphql-testing.md

File metadata and controls

129 lines (106 loc) · 4.26 KB

GraphQL Testing

Testing is very important. Test GraphQL Hotchocolate is possible, something (like DataLoader) can be unit tested, but generally speaking it's better to do integration tests in order to check all of your server components, from the schema to the resolvers/data-loaders. Let's see how using NUnit.

Setup

Let's create a test project:

dotnet new nunit -n graphqlTests
dotnet add ./graphqlTests package HotChocolate.Data.MongoDb --version 12.1.0
dotnet add ./graphqlTests package HotChocolate.AspNetCore --version 12.1.0
dotnet add ./graphqlTests package MongoDB.Driver --version 2.12.1
dotnet add ./graphqlTests package Snapshooter.Nunit --version 0.7.1
dotnet add ./graphqlTests package Mongo2Go --version 3.1.3
dotnet add ./graphqlTests reference ../graphqlServer/graphqlServer.csproj
dotnet sln add graphqlTests

Then test the new project:

dotnet test .\graphqlTests\

Note here that, as suggested by Hotchocolate creators, we use Snapshooter to create snapshot files of the schema, resolver results etc and this drastically simplifies the tests.

To do integration testing, we have to configure services and pipelines in order to hit a real DB. for sake of simplicity, In this demo repo I will use the same db used for graphQL server projects.

So you can see code like the following in the test setups:

[OneTimeSetUp]
public void OnOneTimeSetup()
{
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json")
        .Build();

    var services = new ServiceCollection()
            .AddSingleton<IConfiguration>(config)
            .AddSingleton<MongoContext>()
            .AddScoped(sp => sp.GetRequiredService<MongoContext>().Database.GetCollection<Author>("author"))
            .AddScoped(sp => sp.GetRequiredService<MongoContext>().Database.GetCollection<Publisher>("publisher"))
            .AddScoped(sp => sp.GetRequiredService<MongoContext>().Database.GetCollection<Book>("book"))
            ;
}

Test Schema

Test schema is very simple: we do a complete service setup (without authorization settings) and snapshot the schema created:

[Test]
public async Task Books_verify_schema()
{
    await new ServiceCollection()
                .AddGraphQL()
                .AddQueryType(c => c.Name("Query"))
                .AddTypeExtension<AuthorQueries>()
                .AddTypeExtension<PublisherQueries>()
                .AddTypeExtension<BookQueries>()
                .AddMongoDbFiltering()
                .AddMongoDbSorting()
                .AddMongoDbProjections()
                .AddMongoDbPagingProviders()
                .AddGlobalObjectIdentification()
                .AddType<AuthorType>()
                .AddType<PublisherType>()
                .AddType<BookType>();
                .MatchSnapshotAsync();
}

...
public static async ValueTask<ISchema> MatchSnapshotAsync(this ValueTask<ISchema> task)
{
    ISchema result = await task;
    result.Print().MatchSnapshot();
    return result;
}

Test Resolvers

Testing the resolvers is equally simple with snapshotting.

[Test]
public async Task BookResolver_simple_string_request_test()
{
    IExecutionResult result = await _requestBuilder.ExecuteRequestAsync(@"
    {
        books(first:1){
            nodes {
            title
            }
            totalCount
        }
    }");
    result.ToJson().MatchSnapshot();            
}

Test DataLoaders

DataLoaders can be unit tested as normal C# class. Here I preferred to do an integration tests in order to hit a real db

[Test]
public async Task Loader_simple_test()
{
    var books = CreateBookCollection(
        new Book{ Id = "75f31668-f348-4aa0-88c9-d186e0a6fe4e", Title = "Reconstituirea (Reconstruction)"}
    );
    var (loader, scheduler) = GetDataLoaderUT(books);

    var bookResult = loader.LoadAsync("75f31668-f348-4aa0-88c9-d186e0a6fe4e");
    scheduler.Dispatch();
    var book = await bookResult;

    Assert.IsNotNull(book);
    Assert.That(book.Id, Is.EqualTo("75f31668-f348-4aa0-88c9-d186e0a6fe4e"));
    Assert.That(book.Title, Is.EqualTo("Reconstituirea (Reconstruction)"));
}