SparkyTestHelpers: AppSettings
Tags: csharp, dotnet, testing, unittesting
Published: 2020-02-21 00:35:13

> [**NuGet package**](https://www.nuget.org/packages/SparkyTestHelpers.AppSettings/) | [**Source code**](https://github.com/BrianSchroer/sparky-test-helpers/tree/master/SparkyTestHelpers.AppSettings) | [**API documentation**](https://github.com/BrianSchroer/sparky-test-helpers/blob/master/SparkyTestHelpers.AppSettings/api.md)

Static dependencies cause a lot of problems with code testability. They’re hard to mock, and if tests change static values and don’t clean up after themselves, it can cause other tests to unexpectedly fail.

A common static dependency in .NET (before [.NET Core’s rethinking of how configuration should work](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?tabs=basicconfiguration), anyway) is appSettings values from .config files.

Unit tests can code test values, e.g.: 
```csharp 
ConfigurationManager.AppSettings["key"] = "test value";
```
…but as mentioned above, they have to undo overrides to make sure they don’t affect other tests.

## AppSettingsHelper

This class lets you test with one or more appSettings overrides and automatically roll back the overrides when the test is complete.:

```csharp
using SparkyTestHelpers.AppSettings
...
    AppSettingsHelper
        .WithAppSetting("bar", "test bar value")
        .AndAppSetting("baz", "test baz value")
        .Test(() =>
        {
            // Code to test method that uses "bar" & "baz" 
            // ConfigurationManager.AppSettings values
        });
```

The **WithAppSetting** clause is required. You can use zero or as many additional **AndAppSetting** overrides as you need. The .Test method “calls back” to a test Action that uses the **ConfigurationManager.AppSettings** value(s).

*But there’s a better way...*

## AppSettings.TestDependencyProvider

Code with static dependencies can be made more testable by using a dependency-injectable wrapper around the static code. [SparkyTools.DependencyProvider](https://www.nuget.org/packages/SparkyTools.DependencyProvider/) provides one way to do this.

The [SparkyTools.XmlConfig](https://www.nuget.org/packages/SparkyTools.XmlConfig/) NuGet package has an **AppSettings.DependencyProvider()** method that creates a DependencyProvider wrapping ConfigurationManager.AppSettings.

This (SparkyTestHelpers.AppSettings) package has an **AppSettings.TestDependencyProvider()** method that creates a provider that serves test values from a key/value dictionary:

*Class using appSettings, made testable via* **DependencyProvider**:

```csharp
using SparkyTools.DependencyProvider;
public class Foo
{
  private readonly Func<string, string> _getAppSetting;

  public Foo(DependencyProvider<Func<string, string>> appSettingsProvider)
  {
      _getAppSetting = appSettingsProvider.GetValue();
  }

  public void MethodUsingAppSettings()
  {
    string bar = _getAppSetting("bar");
    string baz = _getAppSetting("baz");  
  }
}
```

*Code using “real”* **DependencyProvider** *that wraps ConfigurationManager.AppSettings:*


```csharp
using SparkyTools.XmlConfig;
...
    var foo = new Foo(AppSettings.DependencyProvider());
```

*Unit test code using dictionary* **DependencyProvider**:

```csharp
using SparkyTestHelpers.AppSettings;
...
    var provider = AppSettings.DependencyProvider(
        new Dictionary<string, string>
        { 
            { "bar", "test bar value" },
            { "baz", "test baz value" }   
        });

    var foo = new Foo(provider);
```
- - -
Happy Testing!