0

I believe I am missing/misunderstanding something fundamental about the way .net5 works. In setting up an integration test environment for my GraphQL API, I am missing the step on how to start the GraphQL server from said test environment.

When I run the main project, the server is started properly and I can navigate to localhost in the browser and successfully execute GraphQL queries/mutations. My goal here is to set up some automated integration tests.

I'm using NUnit as my test runner and am using WebApplicationFactory<Startup> to "start the server" as I understand it.

In my test project, I'm under the impression that WebApplicationFactory<Startup> is supposed to basically use the Startup.cs class from my main project in my test project so that I don't have to duplicate all the settings, configurations, and injected services. Please correct me if that assumption is not correct.

I've pasted the code I think is relevant.

ApiWebApplicationFactory<Startup>

public class ApiWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
{
    public static IConfigurationRoot Configuration { get; set; }

    public ApiWebApplicationFactory()
    {
        var configBuilder = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
        Configuration = configBuilder.Build();
    }

    protected override void ConfigureClient(HttpClient client)
    {
        base.ConfigureClient(client);
        client.BaseAddress = new Uri("https://localhost");
        client.Timeout = new TimeSpan(0, 10, 0);
    }

    // Based on my assumption this class reuses everything in the Startup.cs class
    // I don't actually think this is necessary, but thought it was worth trying
    // the test with and without this code.
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            services
                .AddGraphQLServer()
                .AddQueryType<Query>()
                .AddMutationType<Mutation>()
                .AddType<GraphQLContentItem>()
                .AddType<GraphQLFolder>();
        });
    }
}

OneTimesetUp

[OneTimeSetUp]
public void OneTimeSetUp()
{
    _factory = new ApiWebApplicationFactory<Startup>();
    _client = _factory.WithWebHostBuilder(builder =>
    {
        builder.ConfigureServices(services =>
        {
            services.AddScoped<ICacheRepository, MockCache>();
        });
    }).CreateClient();

    var connString = ApiWebApplicationFactory<Startup>.Configuration.GetConnectionString("DefaultConnection");
    var options = new DbContextOptionsBuilder<CmsContext>()
        .UseMySql(connString, ServerVersion.AutoDetect(connString))
        .Options;

    _dbContext = new CmsContext(options);
    _dbContext.Database.EnsureCreated();
}

Test

[Test]
public async Task Test()
{
    // If I set a breakpoint here, I can't navigate to the URL like I'm expecting to
    var graphQLHttpClient =
        new GraphQLHttpClient(
            new GraphQLHttpClientOptions { EndPoint = new Uri("https://localhost/graphql") },
            new NewtonsoftJsonSerializer(), 
            _client);
            
    var request = new GraphQLRequest
    {
        Query = @"
            query GetCurrentSession() {
                getCurrentSession() {
                    id
                    name
                }
            }",
        OperationName = "GetCurrentSession"
    };

    // Error is thrown here with "Bad Request"
    var response = await graphQLHttpClient.SendQueryAsync<Session>(request);

    // Further code is omitted
}

Please let me know if you see what I am missing. Thanks in advance~

  • A WebApplicationFactory doesn't start the server in a conventional manner, the application never binds a socket on the localhost. Instead it basically creates a fake in memory http server, that can only be communicated with from the HttpClient created from the `CreateClient()` method. I would remove all references to http://localhost and instead use relative links. – Darren Oct 18 '21 at 14:47
  • Ah, that makes a lot of sense. I will give that a try. Thanks for the help – James654987 Oct 21 '21 at 15:00

0 Answers0