What I'm using
I'm using:
- .NET 6 with <Nullable>disable</Nullable>,
- NUnit (3.13.3),
- and System.Configuration.ConfigurationManager.
What I have
Currently, I have a simple solution consisting of 3 projects:
- A class library,
- a console app,
- and a unit test project
The class library has a single class Foo
which uses ConfigurationManager
to read setting from configuration file
using System.Configuration;
namespace ClassLibrary;
public class Foo
{
public static string Bar = ConfigurationManager.AppSettings["setting"];
}
App.Config is located in the solution root, it's linked to each project and looks like this
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="setting" value="Kitty meow" />
</appSettings>
</configuration>
When I use the Foo
class in console app the setting value is read from the file just fine
using ClassLibrary;
Console.WriteLine(Foo.Bar); // Bar property contains the correct value
Console.ReadKey();
However, when I try to use the Foo
class in unit test, the value of Bar
property is null
using ClassLibrary;
using NUnit.Framework;
namespace TestProject;
public class ConfigurationManagerTest
{
[Test]
public void MakeSureThatConfigurationManagerReadsFromFileCorrectly()
{
Assert.That(Foo.Bar, Is.Not.Null); // Bar property is null
}
}
The full source is available on GitHub:
https://github.com/dva-meow/UnitTestConfiguration
What I have tried
I've been trying to figure out what was causing this but had no success. Here's a list of what I've tried:
1. Copying the configuration file — In this SO post as well as in this one a few people mention that it's necessary to link/copy the App.Config file to the unit test project. This is working for the console app but not for the unit test (I've tried both linking and copying the file).
2. Making sure the configuration file is present in the executing directory — This SO answer says that:
When you compile an application, its app.config is copied to the bin directory with a name that matches your exe. For example, if your exe was named "test.exe", there should be a "text.exe.config" in your bin directory.
I made sure this was indeed the case for my project and I can confirm, that the renamed App.Config file is being copied to the bin directory of each project.
3. Investigating when initialization of static field occur — This SO answer suggests that:
Static classes are initialized prior to first use of any static member of that class. Unit Test code is no exception to this rule.
I was experimenting in debug for a while but haven't discovered anything useful. The correct value is present in the console app while in unit test it's always null, regardless of how many times I try to access the Bar
property. (Also, I find this a bit odd as I don't believe it matters at all whether I assert the property for null
right away or assign it to a variable before doing it.)
4. Experimenting with case-sensitivity — I tried renaming the configuration file to rule out the possibility that the ConfigurationManager
is case-sensitive when used in unit tests.
What I need
I could probably come up with some sort of a workaround to avoid this issue but I would very much like to get to the bottom of this. All circumstances seem to be the same for both the console app as well as the unit test project and I'm really confused why it's not working the same in both cases.
What am I doing wrong?