Course contentsShow
← C#
Lesson 1679 of 1,90815. Software Quality and TestingFree lesson

Unit Testing Configuration Providers

Verify that application settings are correctly parsed and applied by the system.

Unit Testing Configuration Providers

In this lesson, you will learn how to verify that your application correctly parses and maps complex settings into strongly-typed objects without spinning up an entire integration environment.

The Problem of Configuration Drift

In modern C# applications, we rarely access IConfiguration keys directly. Instead, we use the IOptions<T> pattern to bind settings to POCOs. A common risk is "configuration drift"—where a developer renames a JSON property or changes a data type, but the application fails to bind it correctly at runtime. Integration tests are too slow to catch these simple mapping errors, so we use unit tests to validate the ConfigurationBuilder and binding logic in isolation.

Testing the Binding Logic

To unit test your configuration provider, you don't need a real appsettings.json file. Instead, you can construct an in-memory collection and use the Microsoft.Extensions.Configuration primitives to test the binding process directly.

Here is how you verify that a provider correctly translates a dictionary of settings into your target class:

[Fact]
public void AppSettings_ShouldBindCorrectly_ToOptionsObject()
{
    // Arrange: Simulate a flat collection of settings
    var settings = new Dictionary<string, string> {
        {"ServiceSettings:TimeoutSeconds", "30"},
        {"ServiceSettings:RetryCount", "3"}
    };

    IConfiguration configuration = new ConfigurationBuilder()
        .AddInMemoryCollection(settings!)
        .Build();

    var options = new ServiceSettings();

    // Act: Bind the configuration to the POCO
    configuration.GetSection("ServiceSettings").Bind(options);

    // Assert: Verify mapping
    Assert.Equal(30, options.TimeoutSeconds);
    Assert.Equal(3, options.RetryCount);
}

Why This Matters

By decoupling the validation of your configuration schema from the application startup, you create a fast feedback loop. If someone deletes a key or introduces a type mismatch (e.g., trying to bind a string to an integer), the unit test fails immediately during the build process. This pattern ensures that your IOptions objects are always accurately populated and ready for dependency injection, effectively serving as a contract between your settings files and your business logic.

Key Takeaway: Use AddInMemoryCollection to verify that your configuration binding logic correctly maps settings to your domain objects without requiring external files or infrastructure.