1

I have reduced this to the simplest possible.

VS2019 MSTest Test Project (.NET Core) template

Default unit test project .

Use nuget to install System.Configuration.ConfigurationManager(5.0.0)

Add app.config file to project (add -> new Item -> select Application Configuration File>

Add entry to config file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
  <add key="TestKey" value="testvalue"/>
</appSettings>
</configuration>

Debug the code below and k is null.

   using Microsoft.VisualStudio.TestTools.UnitTesting;
   using System.Configuration;

   namespace UnitTestProject1
   {
    [TestClass]
    public class UnitTest1
    {
    [TestMethod]
    public void TestMethod1()
    {
        var k = System.Configuration.ConfigurationManager.AppSettings["TestKey"];

    }
  }
 

How do you get the unit test to read the config file?

Bob Clegg
  • 543
  • 1
  • 6
  • 20
  • AppSettings.Settings["TestKey"] ? – agent_bean Dec 16 '20 at 22:51
  • It feels like a weird use case. Can you add some context around what your trying to achieve, I might be wrong but my gut says there is a better way. Be well. – gingerbreadboy Dec 16 '20 at 22:59
  • 1
    To expand on the above. If it's a unit test why not just define this value in the test? You don't need to test the value is correctly picked from the config file, so what benefit does doing this add. I dunno, I don't have context so I may be taking rubbish and that's fine, but it *feels* wrong. – gingerbreadboy Dec 16 '20 at 23:01
  • Looks like this issue were discussed at https://stackoverflow.com/questions/344069/can-a-unit-test-project-load-the-target-applications-app-config-file – Prasad Ramireddy Dec 16 '20 at 23:19
  • The real world use is a unit test for a chunk of code that has a config value read deep in it. Still can't that going but with new info from these answers I am hopeful. – Bob Clegg Dec 18 '20 at 02:51
  • Again, I don't have all the context, but I would want to be thinking about refactoring this up and out **if possible**. Feels like your DI/IOC isn't quite right. I know, is not always possible with legacy code so YMMV :) – gingerbreadboy Dec 19 '20 at 09:59

2 Answers2

2

You have to tell the configuration manager what file to load. Don't rely on the file matching the exe name, etc. Just keep the name as app.config.

System.Configuration.ConfigurationFileMap configMap = new ConfigurationFileMap("./app.config");
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(configMap);
string value = configuration.AppSettings["TestKey”];
jjxtra
  • 19,175
  • 12
  • 90
  • 136
2

If you add this line to your TestMethod, it will tell you what is the name of the config file it is expecting to use:

public void TestMethod1()
{
    string path = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;
    var k = ConfigurationManager.AppSettings["TestKey"];
}

When I ran it, it called the file "(path-to)\testhost.dll.config", not "App.config". So all I did was rename the file to "testhost.dll.config", change its Build Action to "Content" and "Copy always", ran the unit test, and it gave me the right value in var k.

I can't explain why it would look specifically for that filename, but for some reason it is.

Tam Bui
  • 2,709
  • 2
  • 17
  • 23
  • path was C:\temp\Projects Testing\UnitTestProject1\bin\Debug\netcoreapp3.1 File was ReSharperTestRunner64.dll.config. Soo obvious how did I miss it. Thank you – Bob Clegg Dec 17 '20 at 07:10
  • Hahaha, exactly! Soo obvious. Why haven't you submitted that filename to memory yet? You're going to need it five years from now. – Tam Bui Dec 17 '20 at 17:51
  • 1
    Just wasted an hour on this until I found your answer. Thank you. – danny10846 Feb 24 '22 at 14:42