How do I get a c# Unit Test to use App.Config? - c#

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?

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.

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ā€¯];

Related

MStest throwing errors for Class library using multiple config files [duplicate]

This question already has answers here:
Can a unit test project load the target application's app.config file?
(12 answers)
Closed 4 years ago.
I have created a class library MultipleConfigFiles, which has a method getConfigData. This method reads data from config files.
public class Class1
{
public string getConfigData()
{
string configData = ConfigurationManager.AppSettings["key"].ToString();
return configData;
}
}
Now I have a console application ConsoleAppConfig, in which I have given the reference of the class library.In the main method, I have created a object for the library class and called the method.
static void Main(string[] args)
{
Class1 c = new Class1();
string data = c.getConfigData();
Console.Write(data);
}
This console application has 2 different config files dev.config and prod.config. In the main App.config file , I have used configSource to map the appropriate config file.
<appSettings configSource="dev.config" />
Dev.config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="key" value="dev" />
</appSettings>
Till here it is working fine.That is, when I run the console app, the method returns dev.
Now,I have created a MSTest project for this class library.
public class Class1Tests
{
[TestMethod()]
public void getConfigDataTest()
{
Class1 obj = new Class1();
var result = obj.getConfigData();
}
}
Now the problem is, when I run this test, it throws an error saying
"An exception of type 'System.NullReferenceException' occurred in MultipleConfigFiles.dll but was not handled in user code.
Additional information: Object reference not set to an instance of an object."
Since the config files are in ConsoleApplication , the method is not able to read the appsetting variables from there. Is there any way I can maintain the configuration files globally so that both of them use individually , or is there any better way to handle this.
Any inputs are appreciated.Thanks.
Without duplicating the files you can the Link the files in existing Unit Test project.
You can try the same as mentioned in the image Link (https://grantwinney.com/content/images/2014/04/AddExistingFileAsLink-002.png)
Google this term "Visual Studio - Add File As Link" for more Info
Image Credits : https://grantwinney.com

NUnit appSettings file attribute (linked config file) is not seen by ConfigurationManager in test

I have NUnit test (version 2.6.4) test. It uses ConfigurationManager.AppSettings["foo"] to retrive a configuration setting from the app.config file (which is in the test project). This is my App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="bar.config">
<add key="thisSettingIsVisible" value="yes, indeed"/>
</appSettings>
</configuration>
and this is bar.config file:
<appSettings>
<add key="foo" value="this setting isn't visible"/>
</appSettings>
I'm using ReSharper 10 test runner to execute the test. bar.config file is copied to the bin/Debug directory. In fact, that configuration was working some time ago, but stopped. Any clues what can be wrong?
Now, I've figured out a workaround, but I'm not happy with this solution:
private static void InitializeAppSettings()
{
var exeAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyName = exeAssembly.GetName().Name + ".dll";
var testDllFolder = new Uri(System.IO.Path.GetDirectoryName(exeAssembly.CodeBase)).LocalPath;
var openExeConfiguration = ConfigurationManager.OpenExeConfiguration(Path.Combine(testDllFolder, assemblyName));
foreach (var setting in openExeConfiguration.AppSettings.Settings.AllKeys)
{
ConfigurationManager.AppSettings[setting] = openExeConfiguration.AppSettings.Settings[setting].Value;
}
}
BTW. I can't abstract away ConfigurationManager usage form existing, legacy code.
I replicated your use case and found that my additional config worked in the context of an ASP.NET site but the additional appSetting was null in a test project until I changed the Copy to Output Directory property to Copy Always
If you use R# 10.0.0 or R# 10.0.1 - it is a known issue for such builds and it has been fixed in R# 10.0.2 build.

Cannot Use ConfigurationManager inside Unit Test Project

I'm trying to write a unit test for my project, but it will not let me use the Configuration Manager. Right now my project is set up like
ASP.Net application (all aspx pages)
ProjectCore (all C# files - model)
ProjectTest (all tests)
in my ProjectCore, I am able to access the ConfigurationManager object from System.Configuration and pass information onto the project. However, when I ran a test where the ConfigurationManager is involved, I get the error
System.NullReferenceException: Object reference not set to an instance of an object.
Here is an example of the test
using System.Configuration;
[TestMethod]
public void TestDatabaseExists()
{
//Error when I declare ConfigurationManager
Assert.IsNotNull(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString
}
in my other tests, ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString is what I set my data adapter's configuration string to, and returns a null error on the tests but not when I actually use the website. Any ideas?
It could be one of several issues:
You didn't add app.config to your ProjectTest project.
You didn't add connection string in your app.config.
You are doing a unit test and in unit test your concentration should be the particular method trying to test and should remove extraneous dependencies. in this case, try mocking/moleing(use Microsoft Mole and Pex) system.configuration class; that will give a solution for sure.
What I am saying, once you install MS moles-and-pex -> in your test project solution -> right-click the system assembly and choose create mole.
That will give you a mole'ed version of configuration class which in turn will have a mocked version of configuration class -- using which you can bypass the problem you are facing.
You also can use special configuration paths with the ExeConfigurationFileMap:
// Get the machine.config file.
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
// You may want to map to your own exe.config file here.
fileMap.ExeConfigFilename = #"C:\test\ConfigurationManager.exe.config";
// You can add here LocalUserConfigFilename, MachineConfigFilename and RoamingUserConfigFilename, too
System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
It is related to the /noisolation parameter in the command line of mstest.exe.
Omitting the /noisolation parameter, it works.
first of all you must make sure that you have an app.config file in your nunit tests project.
To add it, you can open the project properties (right click on the project)
Enter the details of your connection, it will generate a app.config file or add the right section within :
In your Test class, add the reference to : System.Configuration;
=> using System.Configuration;
For example you could use your connectionString by this way :
[TestFixture]
public class CommandesDALUnitTest
{
private string _connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
[Test]
public void Method_Test()
{
string test = _connectionString;
....
}
}

ConfigurationManager return null instead of string values

I am trying to retrieve values from my App.config file which is stored in my working directory, however when I run the program it returns null. I am very confused why this is so, and have looked over the code many times in an attempt to spot an error.
Here is my App.config file code:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="provider" value="System.Data.SqlClient" />
</appSettings>
<connectionStrings>
<add name="connection" connectionString="Data Source=(local)\SQLEXPRESS;Initial Catalog=Autos;Integrated Security=True;Pooling=False" />
</connectionStrings>
</configuration>
Here is my C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Data;
using System.Data.Common;
namespace DataProviderFun
{
class Program
{
static void Main(string[] args)
{
string p = ConfigurationManager.AppSettings["provider"];
string c = ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
...
When I run this code, p = null and c = null.
I have referenced System.Configuration.dll.
Did you ensure that the config file is placed correctly at the directory from which you're running the application? Is there actually a file called <app name>.exe.config in that directory?
I'm just guessing here - maybe you added the App.Config file in a different project then your exe assembly project...?
By the way, I copied your code and App.Config as is to a clean project, and this code worked for me. So I'd look in the direction of the config file itself and not in the code. The code is fine...
Hope this helps,
Ran
If your config file use in different class library you must change your name YourClasslibraryDllname.dll.config and you must change config file copy to output directory property
Ex:
YourSolution
ClassLibrary_1
ClassLibrary_1.dll.config
ApplicationConfigurationReader.cs
ConfigurationConst.cs
ClassLibrary_2
ConsoleApp
Rename your config file like this YourClasslibraryDllname.dll.config
Open Properties Window
Change Do Not Copy to Copy Always
Add reference -> Assembly -> System.Configuration
Add below clases in ClassLibrary_1 Project
ConfigurationConst Class using System.Configuration;
public static class ConfigurationConst
{
public static KeyValueConfigurationCollection Configs;
}
ApplicationConfigurationReader class using System.Configuration;
internal class ApplicationConfigurationReader
{
public void Read()
{
// read assembly
var ExecAppPath = this.GetType().Assembly.Location;
// Get all app settings in config file
ConfigurationConst.Configs = ConfigurationManager.OpenExeConfiguration(ExecAppPath).AppSettings.Settings;
}
}
Read Config using ClassLibrary_1;
static void Main(string[] args)
{
new ApplicationConfigurationReader().Read();
var Configval = ConfigurationConst.Configs["provider"].Value;
Console.ReadKey();
}
i Hope you can get clean help
In Case all the settings are correct but still if you get null values, Please check your app.config file and replace the xml code as below,
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
</configuration>
Now Run your Code, you might see the proper values
If you have .dll in your debug folder, then rename your confif file to yourprojectname.dll.config. This worked in my case

Is there a standard method to create a configuration file for C# program?

In the past I would just create a text file with key value pairs for example WIDTH=40 and manually parse the file. This is getting a little cumbersome is there a standard way to do this preferably with inbuilt support from Visual Studio or the .NET framework.
Configuration files are one of the built-in templates. Right-click on your project, choose Add->New Item. In the template box, select configuration file.
You could to create an Application Configuration File in Visual Studio. It's basically and XML file which you can to use to save your application configuration data, but it's not meant to be read as an XML file: .net framework provides some classes to interact with it.
This link can provide some background and sample code: Using Application Configuration Files in .NET
You could to place this code inside your .config file:
<configuration>
<appSettings>
<add key="SomeData" value="Hello World!" />
</appSettings>
</configuration>
And you can read it this way in C# (requires a reference to System.Configuration assembly):
Console.WriteLine(
"Your config data: {0}",
ConfigurationManager.AppSettings["SomeData"]);
Note you'll need to escape your data ti fit into a XML file; for instance, a & character would became &
In your C# project look in the folder: Properties and open the file Settings.setting.
Here you can specify settings at the user or application level.
The following code sample shows how to use the settings:
public partial class MyControl : UserControl
{
MyProject.Properties.Settings config_;
public MyControl
{
InitializeComponent();
config_ = new MyProject.Properties.Settings();
}
public void SaveToConfig()
{
// save to configuration file
config_.ReportFileName = dataFileName.Text;
config_.Save();
}
public void LoadFromConfig()
{
string dataFileName = config_.ReportFileName;
}
}
You can also use settings when starting your application, and to modify your settings as you upgrade you application.
static void Main()
{
// if user setting program version user setting is less than
MyProject.Properties.Settings config = new MyProject.Properties.Settings();
string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
if (config.Version != version)
{
// migrate from version 1.0.2 to future versions here...
if (config.Version == null)
{
}
config.Upgrade();
config.Reload();
config.Version = version;
config.Save();
}

Categories