Curently F# FAKE build project from FSharp.Data.GraphQL.Build.slnx starts both FSharp.Data.GraphQL.IntegrationTests.Server.fsproj and star-wars-api.fsproj and executes tests against the real running server.
WebApplicationFactory from Microsoft.AspNetCore.Mvc.Testing NuGet package allows to simplify this by starting a host in tests process.
type IntegrationTestApplicationFactoryBase = WebApplicationFactory<FSharp.Data.GraphQL.IntegrationTests.Server.Program>
type IntegrationTestApplicationFactory () =
inherit IntegrationTestApplicationFactoryBase ()
[<Literal>]
static let graphQLEndpoint = "/GraphQL"
static member GraphQLEndpoint = graphQLEndpoint
member factory.ConfigureHttpClientForTenant (httpClient : HttpClient) =
httpClient.BaseAddress <- Uri (factory.Server.BaseAddress, TestApplicationFactory.GraphQLEndpoint)
member private factory.ConfigureHttpClientForUser (userId : UserId) (httpClient : HttpClient) =
httpClient.DefaultRequestHeaders.Authorization <- AuthenticationHeaderValue ("Bearer", $"{userIdString}")
httpClient.BaseAddress <- Uri (factory.Server.BaseAddress, TestApplicationFactory.GraphQLEndpoint)
member factory.CreateHttpClient ([<Optional>] userId) =
let httpClient = factory.CreateClient ()
factory.ConfigureConsoleHttpClientForUser userId httpClient
httpClient
override factory.ConfigureWebHost builder =
builder.UseEnvironment Environments.Test |> ignore
builder.ConfigureServices (fun services ->
// TODO: Replace services with mocks here
services
|> ignore
// Prevent background service failures from terminating the test host.
// The main app's background services may fail (e.g. due to schema differences
// in the local dev database), but tests don't depend on them.
services.Configure<HostOptions> (fun (options : HostOptions) ->
options.BackgroundServiceExceptionBehavior <- BackgroundServiceExceptionBehavior.Ignore
)
|> ignore
)
|> ignore
base.ConfigureWebHost builder
type StarWarsTestApplicationFactoryBase = WebApplicationFactory<FSharp.Data.GraphQL.Samples.StarWarsApi.Program.Program>
[<AbstractClass; TestClass>]
type TestBase () =
member val TestContext = Unchecked.defaultof<TestContext> with get, set
member test.CancellationToken = test.TestContext.CancellationTokenSource.Token
[<AbstractClass; TestClass>]
type SingleHostIntegrationTestBase () =
inherit TestBase ()
[<DefaultValue>]
static val mutable private application : TestApplicationFactoryBase
static member Application = SingleHostIntegrationTestBase.application
[<ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)>]
static member Initialize (ctx : TestContext) = SingleHostIntegrationTestBase.application <- new TestApplicationFactory (ctx.FullyQualifiedTestClassName)
[<ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)>]
static member Cleanup () : Task = task { do! SingleHostIntegrationTestBase.application.DisposeAsync () }
[<AbstractClass; TestClass; TestCategory (TestCategories.Marten)>]
type IntegrationTestBase ()
=
inherit TestBase ()
[<DefaultValue false>]
val mutable private application : DatabaseTestApplicationFactory
member test.Application = test.application
abstract ConfigureServices : IServiceCollection -> unit
default _.ConfigureServices _ = ()
[<TestInitialize>]
member test.Initialize () : Task = task {
test.application <- 'Factory.Create (test.TestContext, test.ConfigureServices)
do! test.application.InitializeAsync ()
}
[<TestCleanup>]
member test.Cleanup () : Task = task {
match withNull test.application with
| null -> ()
| application ->
// The second test fails for some reason
//do! test.application.DisposeAsync ()
Task.Run (
``function`` =
Func<Task> (fun () -> task {
do! Task.Delay 1000
do! test.application.DisposeAsync ()
})
)
|> ignore
test.application <- Unchecked.defaultof<_>
}
Then tests can create type provider context if needed
open System
open FSharp.Data.GraphQL
//type IntegrationTestsClient = GraphQLProvider<"../../introspection.json", explicitOptionalParameters = true>
type WebApplicationFactory<_> with
member factory.CreateClientContext (userId) =
let httpClient = factory.CreateHttpClient (userId)
let connection = new GraphQLClientConnection (httpClient)
{ ServerUrl = String.Empty; HttpHeaders = Seq.empty; Connection = connection }
type IntegrationTestBase with
member test.CreateClientContext (userId) = test.Application.CreateClientContext (userId)
Curently F# FAKE build project from
FSharp.Data.GraphQL.Build.slnxstarts bothFSharp.Data.GraphQL.IntegrationTests.Server.fsprojandstar-wars-api.fsprojand executes tests against the real running server.WebApplicationFactoryfromMicrosoft.AspNetCore.Mvc.TestingNuGet package allows to simplify this by starting a host in tests process.Then tests can create type provider context if needed