I've created a simple unit test project to read an app.config file. Target framework is Core 2.0. I also created a Core 2.0 console app, to sanity-check myself to make sure I wasn't doing anything weird (same test passed as expected in a .NET 4.6.1 unit test project).
The console app reads the app.config fine, but the unit test method fails and I cannot figure out why. Both are using a copy of the same app.config (not added as a link) and both have the System.Configuration.ConfigurationManager v4.4.1 NuGet package installed.
The App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Test1" value ="This is test 1."/>
<add key="Test2" value ="42"/>
<add key="Test3" value ="-42"/>
<add key="Test4" value="true"/>
<add key="Test5" value="false"/>
<add key="Test6" value ="101.101"/>
<add key="Test7" value ="-1.2345"/>
</appSettings>
</configuration>
The Unit Test
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Configuration;
namespace ConfigTest
{
[TestClass]
public class UnitTest1
{
[TestMethod()]
public void ConfigTest()
{
foreach (string s in ConfigurationManager.AppSettings.AllKeys)
{
System.Console.WriteLine(s);
System.Diagnostics.Debug.WriteLine(s);
}
//AllKeys.Length is 0? Should be 7...
Assert.IsTrue(ConfigurationManager.AppSettings.AllKeys.Length == 7);
}
}
}
The Console App
using System;
using System.Configuration;
namespace ConfigTestApp
{
class Program
{
static void Main(string[] args)
{
foreach (string s in ConfigurationManager.AppSettings.AllKeys)
{
Console.WriteLine(s);
System.Diagnostics.Debug.WriteLine(s);
}
//Outputs 7 as expected
Console.WriteLine(ConfigurationManager.AppSettings.AllKeys.Length);
}
}
}
Given that I'm still pretty new to the whole .NET Core world, am I doing something totally incorrect here? I sort of just feel crazy at the moment...
Usually in .NET Framework projects, any App.config file was copied to the bin folder by Visual Studio, with the name of your executable (myApp.exe.config) so it could be reachable in runtime. Not anymore in .NET Standard or Core Framework. You must manually copy and set the file in the bin/debug or release folder. After that it could be get with something like:
None of the answers given here provide a viable workaround when you're dealing with code accessing directly the static
ConfigurationManager
properties such asAppSettings
orConnectionStrings
.The truth is, it is not possible at the moment. You can read through the discussion here to understand why: https://github.com/dotnet/corefx/issues/22101
There is talk to implement the support for it here: https://github.com/Microsoft/vstest/issues/1758
In my opinion it makes sense to support this scenario since it's been working on the .NET Framework plus
System.Configuration.ConfigurationManager
is a .NET Standard 2.0 library now.A hacky, but working way is to copy the config to the same folder as an entry assembly, whatever it is:
Apart from adding this class, the only thing to make it work is to include
app.config
file in test project (without any copying options). It should be copied to the output folder as<your test project name>.dll.config
at the build step, because it's kind of default logic.Note the documentation for
OneTimeSetUpAttribute
:Although it should work for parallel test runs for a single project, there could be obvious troubles when running two test projects simultaneously, since the config would get overwritten.
However, it is still suitable for containerized test runs, like in Travis.
I came across the same issue with my xunit tests and solved it by using the instance of Configuration from ConfigurationManager. I put the static (normal) way it works in core, framework (but not unit tests) before I show the alternative way it works in all three:
And here is a similar/related issue. In case anyone needs to get a section you can do a similar thing, though the type must change in the app config:
Code to grab section:
I feel like I am also crazy, and I know there are newer ways of doing config in core, but if one wants to do something cross-platform this is the only way I know how. I'd be very interested if anyone has alternatives
The
ConfigurationManager
API will only use the configuration of the app that is currently running. In a unit test project, this means the app.config of the test project, not the console application..NET Core Applications aren't supposed to use app.config or
ConfigurationManager
, as it is a legacy "full framework" configuration system.Consider using
Microsoft.Extensions.Configuration
instead to read JSON, XML or INI configuration files. See this doc: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configurationAdd the configuration file
First, add a appconfig.json file to the Integration test project
Configure the appconfig.json file to be copied to the output directory by updating
Add NuGet package
Use the configuration in your unit tests