9
votes

I am using .NET Core 2.2 IHostBuilder (Generic Host Builder) to build a console app running message streaming app as a BackgroundService (IHostedService). https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-2.2

This is not the IWebHostBuilder that is typically used for hosting an ASP.NET Core web app.

I'd like to build some basic integration test to validate graceful shutdowns and the IoC configuration. I want to start a TestServer that hosts my IHostBuilder host. I don't need to serve any kinds of request.

I've done this kind of thing with IWebHostBuilder and TestServer in Microsoft.AspNetCore.TestHost. However, there is no support for IHostBuilder, only IWebHostBuilder. https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.testhost.testserver.-ctor?view=aspnetcore-2.2#Microsoft_AspNetCore_TestHost_TestServer__ctor_Microsoft_AspNetCore_Hosting_IWebHostBuilder_

I know IHostBuilder will replace IWebHostBuilder in .NET Core 3.0 and TestServer there will support this. Trying to find a way to do this in .NET Core 2.2.

1
Why do you need TestServer? You can build a generic host from your test application, run it with RunAsync() and test whatever you want to test. The only disadvantage is you need to repeat all your DI registration and configuration in test applicationOlegI
@Olegl do you have an example? One thing I'd like to do is test graceful shutdown of my application when the host sends a SIGTERM. Not sure how I'd do that with a full integration test. Another use case is how I said in OP, I need to verify the .NET Core IoC container is configured correctly e.g. I can get select services out of the contain and the app starts up correctly with all the needed dependencies. I've done this kind of thing in ASP.NET web apps and IWebHostBuilder hosted in TestHost. Don't see any similar option for IHostBuilder.Dude0001
do you use IHostedService?OlegI
@Olegl yes I am using BackgroundService which implements IHostedServiceDude0001
@Dude0001 For testing IoC you can simply resolve all registered services (ignoring open generic interfaces like IRepository<>) and all controllers. It should be sufficient. And you don't need to run the whole application for that.Vladimir Serykh

1 Answers

0
votes

I realize this might not be what you had in mind, but you could test this with a script.

It checks the app doesn't crash on start and that it can be stopped with SIGTERM.

test-start-stop.sh:

#!/usr/bin/bash

# Exit on error
# https://stackguides.com/questions/19622198/what-does-set-e-mean-in-a-bash-script
set -e

# Publish binary
# https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
dotnet publish -r linux-x64 -o publish app

# Run in background and save process ID
# https://stackguides.com/questions/1908610/how-to-get-pid-of-background-process
./app/publish/app & 
APP_PID=$!

# Wait until app is started
sleep 5s

# Send SIGTERM
kill -SIGTERM $APP_PID

# Wait for process exit
wait $APP_PID