Dependency Injection in XUnit - including logging

Dependency Injection in XUnit CAN be done, including logging to unit test output. Simply add a Startup.cs that looks like this:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Xunit.DependencyInjection.Logging;

namespace Vendor.Api.Test;

public class Startup
{
	public static void ConfigureServices(IServiceCollection services)
	{
		// Load config
		var config = new ConfigurationBuilder()
			.AddJsonFile("../../../appsettings.json", true)
			.AddEnvironmentVariables()
			.AddUserSecrets<Startup>()
			.Build();

		services
			.AddLogging(lb => lb
				.AddDebug()
				.AddFilter(level => level >= LogLevel.Debug)
				.AddXunitOutput()
			)
			.AddTransient(s =>
			{
				var options = config.GetSection("VendorClientOptions").Get<VendorClientOptions>()
					?? throw new FormatException("Configuration is missing a valid VendorClientOptionssection");
				options.Validate();
				return new VendorClient(options, s.GetRequiredService<ILogger<VendorClient>>());
			})
			;
	}
}

After that, your Unit Test file can look like this:

using FluentAssertions;

namespace Vendor.Api.Test;

public class UserTests(VendorClient client)
{
	[Fact]
	public async Task Get_Page_Succeeds()
	{
		// Arrange
		var result = await client.Users.GetAsync(default);
		result.Should().NotBeNull();
	}
}

To see it in action, check out this repo: https://github.com/panoramicdata/Datadog.Api/

We have utilized this in a few places, for example DataMagic, where we have a custom WebApplicationFactory to mimic the project you are testing, mostly used for integration tests. However, it’s quite challenging when someone makes changes to the underlying project (i.e. adding more services and dependencies) without updating the test project, so the next person trying to run the test cases is caught off-guard by not being able to run the test project.

I presume this could be used to inject AutoMapper for testing mapping between different models / entities in unit tests…?

You certainly could :slight_smile: