1

I have a console app constructed using the following code:

public partial class Program
{
    private static async Task<int> Main(string[] args)
    {
        Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(cfg =>
                {
                    cfg.SetBasePath(contentRootFull);
                    cfg.AddJsonFile($"appsettings.{environment}.json", false, true);
                    cfg.AddEnvironmentVariables().Build();
                })
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddTransient<IMyService, MyService>();
                    services.AddSingleton<MyConsoleApp>(); // Register your main application class
                })
                .Build()
                .Services.GetRequiredService<MyConsoleApp>() // Resolve your main application class
                .Run(args); // Execute your application logic
}
public partial class Program { } // so you can reference it from tests

ASP.Net Core uses WebApplicationFactory<TStartup>. Is there any similar mechanism to do integration tests with a console application which uses dependency injection?

1
  • That depends on what MyConsoleApp does, and how much it really knows about the outside world. Commented Oct 5 at 9:16

1 Answer 1

1

There is nothing build-in AFAIK (and repeating it would be kind of cumbersome - WebApplicationFactory does some dirty magic, similar to one described here for EF Core), especially that you are not leveraging the standard worker service setup.

Probably the easiest approach would be to move the host setup into a separate internal method and access it from the tests (via InternalsVisibleTo see for example this answer):

public partial class Program
{
    private static async Task<int> Main(string[] args)
    {
        CreateHostBuilder(args)
            .Build()
            .Services.GetRequiredService<MyConsoleApp>() // Resolve your main application class
            .Run(args); // Execute your application logic
    }

    internal static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration(cfg =>
        {
            cfg.SetBasePath(contentRootFull);
            cfg.AddJsonFile($"appsettings.{environment}.json", false, true);
            cfg.AddEnvironmentVariables().Build();
        })
        .ConfigureServices((hostContext, services) =>
        {
            services.AddTransient<IMyService, MyService>();
            services.AddSingleton<MyConsoleApp>(); // Register your main application class
        });
}

If you switch to the worker service template you can try the workarounds provided here - How to start a full .NET Core Worker Service in an integration/ end-to-end test? .

P.S.

public partial class Program { } // so you can reference it from tests is not needed since you are not using top-level statements and already had declared Program class.

Sign up to request clarification or add additional context in comments.

2 Comments

Even with this pumbling in place, how do the integration tests access the required DI services?
The same way your console app does, you call .Program.CreateHostBuilder() and then rewire needed services and run the app.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.