I want dotnet test to handle environment variables. On *nix systems I should be able to type MyEnvVar=Hello dotnet test and then be able to access that variable within my tests.

Creating a basic test

Create a new xUnit project and add our favorite assertion library Shouldly.

dotnet new xunit
dotnet add package Shouldly

Our first and only test will expect an IConfiguration object to be injected at runtime and we’ll assert that our environment variable MyEnvVar is set to Hello.

using Microsoft.Extensions.Configuration;
using Xunit;
using Shouldly;

namespace MyTestProject
{
    public class UnitTest1
    {
        public readonly IConfiguration _config;

        public UnitTest1(IConfiguration config)
        {
            _config = config;
        }

        [Fact]
        public void Test1()
        {
            _config.GetValue<string>("MyEnvVar").ShouldBe("Hello");
        }
    }
}

Injecting environment variables

The above test will fail because the IConfiguration object is not available. Xunit.DependencyInjection lets us configure a Startup similar to how we would in an AspNetCore web project.

dotnet add package Xunit.DependencyInjection
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables

After adding the packages we add the Startup class. Using ConfigureHost within this class, we can call AddEnvironmentVariables.

public class Startup
{
    public void ConfigureHost(IHostBuilder hostBuilder)
    {
        var config = new ConfigurationBuilder()
            .AddEnvironmentVariables()
            .Build();

        hostBuilder.ConfigureHostConfiguration(builder => builder.AddConfiguration(config));
    }
}

Now when we run our test with MyEnvVar=Hello dotnet test we get a passing result.

Debugging in VSCode

When we debug the test in Visual Studio Code the test still fails however. This is because we haven’t set the environment variable when debugging. To do so, add the following snippet to .vscode/settings.json:

{
    "csharp.unitTestDebuggingOptions": {
        "env": {
            "MyEnvVar": "Hello",
        }
    }
}

Debug the test and now it passes!

Conclusion

Xunit.DependencyInjection has not only given an easy way to access environment variables in our tests, but we’ve also got Dependency Injection (see ConfigureServices) and, a sneaky way to perform global test setup tasks without the need for collection fixtures.

Full source