Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs
Contact   •   Articles   •   Products   •   Support   •   Search
Ad-free experience sponsored by:
ASPOSE - the market leader of .NET and Java APIs for file formats – natively work with DOCX, XLSX, PPT, PDF, images and more

Accessing Configuration in .NET Core Test Projects

On this page:

If you've been following my blog you know I've written a bit about how the configuration system works in .NET Core and specifically in ASP.NET Core using the dependency injection system:

Both posts describe how you can set up configuration using the various now automatically configured Configuration services in the ASP.NET Startup class and its ConfigureServices() method.

But how do you do this in a Test or any other ASP.NET Core project where configuration isn't automatically configured?

Why Configuration? My simple Use Case - Sensitive Values

When running test projects it's often possible to get away without having to configure a configuration class and just provide explicit values. But often you actually need full dependency injection to be hooked up in order to get Configuration injected into dependencies which brings up two issues:

  • How to get access to the Configuration Provider
  • Hooking up Dependency Injection so Configuration can be injected

My first use case is simple and doesn't require dependency injection: I simply need configuration to handle reading some configuration information in order to test sending an email to check out a new mail provider. I explicitly need to make it so I don't hardcode the sensitive email values and they don't end up in my Git repo. So it would be nice to use UserSecrets as well as get the values from the already existing configuration object config in appSettings.json - same as the Web application that actually runs this code.

The second scenario involves using a business object that also uses this email sending logic in an integration test. Here the configuration object is injected into the business object so I need to have dependency injection available.

Let's take a look at both of these scenarios.

IConfiguration in non-ASP.NET Projects

ASP.NET Core 2.0 now automatically provides an IConfiguration provider that handles input from appsettings.json (including the .Development file), UserSecrets and Environment variable which is great. Configuration is such a core thing that almost every application needs it and with ASP.NET Core 2.0 you don't have to worry about setting up the configuration system manually.

However in a test project that onus falls on you. Unfortunately it's not quite so easy to do this as in ASP.NET because test projects don't automatically configure either a Dependency injection container with common objects, or a configuration provider, so this has to be handled manually.

Fortunately the process to do this is pretty straight forward.

Setting up and Retrieving a Raw Configuration Object

In my test projects I generally add a TestHelper class that provides a few commonly used values, but I also add a few helper methods and one of the methods I typically create is a GetApplicationConfiguration() class. In this application I have a configuration class call KavaDocsConfiguration which is a nested class that contains a bunch of values along with a nested Email object that contains the configuration values I need for my mail test code.

Here's what my configuration in appsettings.json looks like:

// appsettings.json
  "Logging": {...},
  "KavaDocs": {
    "ApplicationName": "KavaDocs",
    "ConnectionString": null,    
    "ApplicationBasePath": "/",
    "ApplicationHomeUrl": "https://localhost:5000",
    "Email": {
      "MailServer": null,
      "MailServerUsername": null,
      "MailServerPassword": null,
      "SenderName": "Kava Docs Administration",
      "SenderEmail": "support@kavadocs.com",
      "AdminSenderEmail": "support@kavadocs.com",
      "UseSsl": true

The UserSecrets JSON data then overrides the sensitive values that are stored outside of the project root so they don't get checked into Git. The file is secrets.json in the local user's User Secrets location:

  "KavaDocs": {
    "ConnectionString": "server=.;database=kavadocs;integrated security=true;",
    "Email": {
      "MailServer": "smtp.mailserver.org",
      "MailServerUsername": "seekrity@darko.com",
      "MailServerPassword": "123456c37a623c686f04ab654321",
      "UseSsl": true

To access the configuration I have to build an IConfigurationRoot explicitly, which is the part that ASP.NET handles explicitly. Once I have the config root I can then bind it to an object instance.

Here are a couple of helpers that configure configuration root and provide an instance of a configuration object - we'll use both of these methods for different purposes later:

public static IConfigurationRoot GetIConfigurationRoot(string outputPath)
    return new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", optional: true)

public static KavaDocsConfiguration GetApplicationConfiguration(string outputPath)
    var configuration = new KavaDocsConfiguration();

    var iConfig = GetIConfigurationRoot(outputPath);


    return configuration;

Notice that the code needs a basepath in order to find the appsettings.json file which is going to be the output path for the file in the test project. I copied this file from my Web Project so I get the same configuration settings and then make sure I mark it as copy to the output folder:

In order for UserSecrets to work in a test project a little extra effort is required since test projects don't let you just edit the value in Visual Studio as you can in a Web Project. I added my UserSecrets key from the Web project into test project's .csproj file configuration:


so now I'm also looking at the same UserSecrets values that my Web project is looking at. Yay!

Using the Configuration Object Explicitly

In my test project using NUnit I can now pull this value out as part of the initialization and store it as a property on my test object:

public class SmtpTests
    private KavaDocsConfiguration configuration;

    public void Init()
        configuration = TestHelper.GetApplicationConfiguration(TestContext.CurrentContext.TestDirectory);
    public async void SendEmailTest()
        var smtp = new SmtpClientNative();

        // this code here uses the configuration
        smtp.MailServer = configuration.Email.MailServer;
        smtp.Username = configuration.Email.MailServerUsername; 
        smtp.Password = configuration.Email.MailServerPassword; 

        smtp.SenderEmail = "West Wind Technologies <info@west-wind.com>";
        smtp.Recipient = "test@gmail.com";

        smtp.Message = "Hello from Mail Gun. This is a test";
        smtp.Subject = "Mailgun Test Message";

        Assert.IsTrue(await smtp.SendMailAsync(),smtp.ErrorMessage);


The test method then uses the configuration values and I'm off to the races. The values are read from both appSettings.json and from UserSecrets.

This works great and if all you need is a configuration object to read a few values this approach is easy and sufficient.

Setting up Dependency Injection

For the second use case I mentioned in the intro I need Configuration to come from Dependency injection in order to inject it into child objects in the dependency chain. To do this I need to a little more work setting up the Dependency provider in the configuration. The business object in this case has a number of dependencies on a EF DbContext as well as the configuration.

In order to do this I can set up the dependency injection in the initialization of the class:

public class SmtpTests 
    private ServiceProvider serviceProvider;
    private KavaDocsConfiguration configuration;        
    private UserBusiness userBusiness;
    public void Init()
       configuration = TestHelper.GetApplicationConfiguration(TestContext.CurrentContext.TestDirectory);
       var services = new ServiceCollection();
       // Simple configuration object injection (no IOptions<T>)
       // configure EF Core DbContext - using the configuration
       services.AddDbContext<KavaDocsContext>(builder =>
           var connStr = configuration.ConnectionString;
           if (string.IsNullOrEmpty(connStr))
               connStr = "server=.;database=KavaDocs; integrated security=true;MultipleActiveResultSets=true";
           builder.UseSqlServer(connStr, opt =>
       // has a depedency on DbContext and Configuration
       // Build the service provider
       serviceProvider = services.BuildServiceProvider();
       // create a userBusiness object with DI    
       userBusiness = serviceProvider.GetRequiredService<UserBusiness>();

The code creates a services collection and adds the various dependencies needed for this particular test class. If you end up doing this for a bunch of classes this configuration code could also be moved into the test helper which could return an object with all the dependencies.

So this code adds the configuration, a DbContext, and a business object into the service provider.

In my business object I have a method that handles the email sending I showed earlier internally and I can now load a user and run an integration test sending a validation key:

public void UserSendEmail()
    // connection string should be set from config
    var user = userBusiness.GetUser(TestHelper.UserId1);
    var validationKey = user.ValidationKey;


And there you have it - injected values in your tests.

IOptions instead of raw Configuration

If you'd rather inject IOptions<T> rather than the raw configuration instance you can change the Init() code slightly and use the following:

var services = new ServiceCollection();

// IOption configuration injection

var configurationRoot = TestHelper.GetIConfigurationRoot(TestContext.CurrentContext.TestDirectory);

serviceProvider = services.BuildServiceProvider();

// to use (or store in )
iConfig = serviceProvider.GetRequiredService<IOptions<KavaDocsConfiguration>>()
var server = iConfig.Value.Email.MailServer;

Usually I try to avoid IOptions<T> for the sheer ugliness of the intermediate interface, and unless you need the specific features of IOptions<T> (see my previous article) I much rather just use the raw configuration object.


Using Configuration in non-ASP.NET projects is not real obvious or at least it wasn't for me so hopefully this post provides a simple overview on how you can get the same configuration you might be using in your main application to also work inside of your test or other non-ASP.NET Projects.

this post created and published with Markdown Monster
Posted in .NET Core  ASP.NET Core  

The Voices of Reason


Kevin Rich
February 19, 2018

# re: Accessing Configuration in .NET Core Test Projects

This is great. I was goofing with this issue just last week, but hadn't gotten around to flushing out a solution. Which packages (or metapackages) are you using in your test project for the configurations? Microsoft.Extensions.Configuration doesn't seem to cover all of the extensions methods for the ConfigurationBuilder.

February 19, 2018

# re: Accessing Configuration in .NET Core Test Projects

Thanks. Useful info for integration test scenarios (as per you example) but worth pointing out (to others) that this should not be necessary in unit tests and if you need config files and DI for these kinds of tests then you are probably doing something wrong.

Dmitry Pavlov
February 19, 2018

# re: Accessing Configuration in .NET Core Test Projects

I decided to just use my "Testing" environment but with real host. This way I can access any injected service (including configuration related ones) via GetService(). Of course in this case the tests are integration ones rather than unit tests, but for unit tests it's anyway mocking should be used instead of accessing configuration files.

public class BaseTestServerDependent 
    public TestServer Server { get; }
    public HttpClient Client { get; }

    public TestServerDependent()
        ServiceCollectionExtensions.UseStaticRegistration = false;
        var hostBuilder = new WebHostBuilder()

        Server = new TestServer(hostBuilder);
        Client = Server.CreateClient();

    public TService GetService<TService>()
        where TService : class
        return Server?.Host?.Services?.GetService(typeof(TService)) as TService;

As an example of the test class:

public class MyTests : TestServerDependent
    public void Should_Access_Injected_Services()
        var mySettings = GetService<IOptions<MySettings>>();

        var myService = GetService<IMyService>();

        // ... the rest of the test ...

Hope that helps as well.

Rick Strahl
February 21, 2018

# re: Accessing Configuration in .NET Core Test Projects

@Jav - I'm not unit testing expert, but do you want to expand on that? How could you possibly test a component that has nested dependencies? At some point you'll have to test higher level components that have dependencies and that point you will most likely need DI to make that happen. Doing low level component unit tests w/o dependencies (or manually created dependencies) only get you so far in even a medium complex solution?

Andrew Lock
February 23, 2018

# re: Accessing Configuration in .NET Core Test Projects

Great post as always Rick. One thing, rather than copying the settings file from your web project to your test file, I'd suggest linking it. That way if your make changes to the settings file, your test project is updated at the same time. https://andrewlock.net/sharing-appsettings-json-configuration-files-between-projects-in-asp-net-core/

Rick Strahl
March 01, 2018

# re: Accessing Configuration in .NET Core Test Projects

@andrew - nice - didn't realize you could do that although I have to say I don't really see that use case. I can use UserSecrets for that scenario just as easily since multiple projects can share the same UserSecrets store on a local machine.

Thanh Doan
March 28, 2018

# re: Accessing Configuration in .NET Core Test Projects

Hi Rick,

Thank you for your great post. I followed your post and now I am able to run some tests for my configuration. I am using XUnit.

However, I am trying to test the way I managed secret/sensitive data configuration. Basically, I will have a default appsettings.json which has sensitive data configuration is empty of null like yours. I want to override those data configuration by Environment Variables. Therefore, I am using IFixture in XUnit to read an json file in order to set up the Environment variables. If I put tests into two different projects such as Dev Test in Dev project(not using IFixture) and Stagging Test in Stagging project using IFixture then they are all green. However, I put it into same project then some failed.

Any ideas for that issue?


August 20, 2018

# re: Accessing Configuration in .NET Core Test Projects

Hi, Thank you for your post very usefull. I found also an easy way to get the configuration file


Justin James
August 21, 2018

# re: Accessing Configuration in .NET Core Test Projects

For .NET Core 2.1 in order for the TestHelper.GetIConfigurationRoot code to work I had to add some nuget packages. Looks like they split the different configuration options into different nuget packages. Below is the different packages that I had to add.

SetBasePath and AddJsonFile => Microsoft.Extensions.Configuration.Json

AddUserSecrets => Microsoft.Extensions.Configuration.UserSecrets

AddEnvironmentVariables => Microsoft.Extensions.Configuration.EnvironmentVariables

September 28, 2018

# re: Accessing Configuration in .NET Core Test Projects


Following additional packages are required.

Setting the base path of the app with SetBasePath. SetBasePath is made available to an app by referencing the Microsoft.Extensions.Configuration.FileExtensions package. Resolving sections of configuration files with GetSection. GetSection is made available to an app by referencing the Microsoft.Extensions.Configuration package. Binding configuration to .NET classes with Bind and Get. Bind and Get are made available to an app by referencing the Microsoft.Extensions.Configuration.Binder package. Get is available in ASP.NET Core 1.1 or later.

October 18, 2018

# re: Accessing Configuration in .NET Core Test Projects

Very useful post. Thanks Also for missing packages, the search box in MSDN is (finally) pretty handy, so queries by extension methods take you to the missing DLL.


November 07, 2019

# re: Accessing Configuration in .NET Core Test Projects

I thought this post is about accessing configuration in tests but the quite important method TestHelper.GetApplicationConfiguration is not shown, no link to github repo anything

Rick Strahl
November 07, 2019

# re: Accessing Configuration in .NET Core Test Projects

@Daniel - Uhm - it's there. First C# code snippet.

Coy Meeks
January 07, 2020

# re: Accessing Configuration in .NET Core Test Projects

Good stuff, Rick! To heck with mocking IConfig when you can just use the real thing! 😃

I wanted to check with you to see if you've ported this to work with Xunit. On my end, it doesn't appear that you need to specify the outputPath of the config and I wanted to confirm there would be no issues. Thanks again!

February 08, 2020

# re: Accessing Configuration in .NET Core Test Projects


I was wondering if what is explained in this article would be a solution for another kind of project than a Test.

I basically need to access User Secrets in a DAL project that is referenced into an Asp.Net Core project.

It's basically to provide my DAL with a connectionString and InvariantName. That seems "a lot of work" for two strings value..

What would you advise?

Thank you

ps : I am new to development

Rick Strahl
February 08, 2020

# re: Accessing Configuration in .NET Core Test Projects

@Franz - you should not use UserSecrets in production since it won't be available on a deployed machine most likely. UserSecrets is just available on the local dev machine and it works because it's only part of the IConfiguration chain of providers. IOW, in development the value is caught first from UserSecrets but in production, no user secrets so the configuration is actually pulled from the configuration file (or whatever other providers like Azure Key Vault) are set up.

You can roll your own configuration manager and store things in a JSON file, but the config system in .NET does all that for you. The downside is that if DI is not auto-provided you have to configure the configuration yourself as outlined in this post.

February 19, 2020

# re: Accessing Configuration in .NET Core Test Projects

Great post - this is exactly what I've done with my test project, which is being used to drive a number of BDD tests with Specflow. Question though, although this is good from the perspective of associating interfaces with classes and for managing lifetimes and singletons etc. it feels like its only half-working since there is no corresponding constructor injection etc. Resolving dependencies still requires either ActivatorUtilities or the Service locator (anti)pattern? Is it possible to turn on the automatic resolution of these interfaces through e.g. Constructor injection in an test project?

Rick Strahl
February 20, 2020

# re: Accessing Configuration in .NET Core Test Projects

@Jason - I think we need to roll our own and provide our own abstraction as I did in the example here.

It sure would be nice if this was baked in somehow, but given that you can use all sorts of different testing frameworks to run .NET Core test, I think we'll be stuck with the hand rolled approach.

Microsoft could provide a default implementation of test helpers that could be used, but the testing space is so opinionated and people likely would just complain that it doesn't do this or that being a constant source of noise. Building a basic test helper like the above isn't a big deal and it's a one time thing per project so not so bad...

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2020