Integration test with Hotchocolate GraphQL and TestServer in C#

3.1k Views Asked by At

I have an ASP.NET Core Api (.NET 6.0) with REST- and GraphQL-endpoints. The GraphQL-endpoints are implemented with Hotchocolate (12.6.0).

For testing the REST endpoints I create a TestServer like this:

protected static async Task<TestServer> CreateServer()
{
     IHostBuilder webHostBuilder = new HostBuilder();
     webHostBuilder.UseContentRoot(Directory.GetCurrentDirectory());

     webHostBuilder.ConfigureWebHost(webBuilder =>
          {
               webBuilder
                    .UseTestServer()
                    .UseEnvironment("Test")
                    .ConfigureAppConfiguration((_, config) =>    
                         config.AddJsonFile("appsettings.Test.json"))
                    .UseStartup<AuthenticatedTestStartup>();
           });

     IHost host = await webHostBuilder.StartAsync();
     return host.GetTestServer();
}

AuthenticatedTestStartup derives from Startup and overrides some methods there, e.g. the database configuration. Using the test server created above I can perform integration tests by using the .CreateClient() method which returns an HttpClient object. With thìs client I am able to call the REST endpoints. This works very fine.

My question is now: Is there a way to use this test server for integration tests agains the GraphQL endpoints and if yes: how? If not: What are the alternatives to test the GraphQL endpoints programatically against a test database?

2

There are 2 best solutions below

0
On

To conduct integration tests you can use "TestServer" provided by Microsoft.AspNetCore.TestHost

Here is basic setup documentation: https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-7.0

It works as good with standard REST endpoints as with GraphQL server. I've setup it according to documentation and I'm working with HotChocolate 13 server and all looks good.

Remember though to correctly choose and use GraphQl endpoint URL/URI (default will be something like "http://localhost/graphql" where "http://localhost" is base url provided by TestServer and "/graphql" is default for hotchocolate if you didn't change it. You need to specify it as URI route for http requests.

You can then use WebApplicationFactory to get HttpClient and use standard POST requests with proper body to hit GraphQl API. Probably you can also incorporate more robust graphQl clients to make requests (like StrawberryShake client for C# in example).

Final flow would look like:

  1. Setup TestServer to work and host your API AspNetCore project (it might involve setting up databases or other infrastructure which you'll need for tests)
  2. Get HttpClient from WebApplicationFactory
  3. Create integration tests using that HttpClient and POST request (or use more specific graphQL clients) and hit your API endpoints with proper URIs.

Hopefully that helps.

0
On

As GraphQL is server over HTTP you can test it the same way as an normal REST endpoint.

But if you do not need HTTP for your tests I would recommend to use a in memory server as it is way faster.

// arrange
var executor = await new ServiceCollection()
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .BuildRequestExecutorAsync();

// act
var query = QueryRequestBuilder.New()
  .SetQuery("{ foo }")
  // you can also add a test principal if you want to test authorised
  // resolvers
  .AddProperty(nameof(ClaimsPrincipal), CreatePrincipal())
  .Create()
var result = executor.ExecuteAsync(query);

// assert
// assert here