dotnet / dotnet/aspnetcore

[.NET Tutorial]: Integration testing a Worker Service

Open
#54,025 5 comments 10 reactions 0 assignees View on GitHub
area-hosting Docs
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### URL

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

### Operating system

Windows

### More information about your system

_No response_

### Description

The integration testing tutorial contains a very detailed description of how to run integration tests for web apps using the [WebApplicationFactory](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.testing.webapplicationfactory-1).

However, I have a **worker service** which I want to test in the same way. How do I do that?

## Example

Given this worker service:
`````csharp
// Program.cs

using SampleWorker;

IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services => { services.AddHostedService(); })
.Build();

host.Run();
`````

````csharp
// Worker.cs

public class Worker : BackgroundService
{
private readonly ILogger _logger;

public Worker(ILogger logger)
{
_logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// - connect to a middleware (data source)
// - connect to database (data sink)
// - received events from middleware, transform + persist in database
}
}
````

I want to be able to write an end-to-end test which provides data source and sink via testcontainers (works) and the unit under test, the worker service, somehow directly via .NET Core. With an web application you would use the WebApplicationFactory. I am looking for a way to do the same with a Worker service.

Here is the test I'd like to be able to write:
````csharp

public class E2eTest
{
///
/// Tests the full round trip from an event being
/// - picked up by the worker service
/// - processed and transformed
/// - persisted to the database.
///
[Fact]
public void EventIsProcessedAndWrittenToDatabase()
{
// arrange
// - start middleware as data source (testcontainers)
// - start database as data sink (testcontainers)

// TODO there is no WorkerFactory.
// How can I start my SampleWorker with all the config in Program.cs ?
var unitUnderTest = new WorkerFactory();

// act
// - publish an event to the middleware (data source)

// assert
// - check that there are entries in the database (data sink)
}
}
````
I've got a similar version of this test already working by [running the SamplerWorker also as a Docker container](https://dotnet.testcontainers.org/api/create_docker_image/). However, I want to be able to easily debug my unit under test which gets really complicated with my current Docker approach.

How can directly start the worker service in my test ? Thank you for your support!

fyi: I've also asked this question on [Stackoverflow](https://stackoverflow.com/questions/77211786/how-to-start-a-full-net-core-worker-service-in-an-integration-end-to-end-test).

### dotnet --info

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.