I am unit testing a .NET application (.exe) that uses an app.config file to load configuration properties. The unit test application itself does not have an app.config file.
When I try to unit test a method that utilizes any of the configuration properties, they return null. I'm assuming this is because the unit test application is not going to load in the target application's app.config.
Is there a way to override this or do I have to write a script to copy the contents of the target app.config to a local app.config?
This post kind-of asks this question but the author is really looking at it from a different angle than I am.
EDIT: I should mention that I'm using VS08 Team System for my unit tests.
In Visual Studio 2008 I added the app.config
file to the test project as an existing item and selected copy as link in order to make sure it's not duplicated. That way I only have one copy in my solution. With several test projects it comes in really handy!
https://i.stack.imgur.com/Bl8Ss.png
https://i.stack.imgur.com/j0DWV.png
The simplest way to do this is to add the .config
file in the deployment section on your unit test.
To do so, open the .testrunconfig
file from your Solution Items. In the Deployment section, add the output .config
files from your project's build directory (presumably bin\Debug
).
Anything listed in the deployment section will be copied into the test project's working folder before the tests are run, so your config-dependent code will run fine.
Edit: I forgot to add, this will not work in all situations, so you may need to include a startup script that renames the output .config
to match the unit test's name.
Whether you're using Team System Test or NUnit, the best practice is to create a separate Class Library for your tests. Simply adding an App.config to your Test project will automatically get copied to your bin folder when you compile.
If your code is reliant on specific configuration tests, the very first test I would write validates that the configuration file is available (so that I know I'm not insane) :
<configuration>
<appSettings>
<add key="TestValue" value="true" />
</appSettings>
</configuration>
And the test:
[TestFixture]
public class GeneralFixture
{
[Test]
public void VerifyAppDomainHasConfigurationSettings()
{
string value = ConfigurationManager.AppSettings["TestValue"];
Assert.IsFalse(String.IsNullOrEmpty(value), "No App.Config found.");
}
}
Ideally, you should be writing code such that your configuration objects are passed into your classes. This not only separates you from the configuration file issue, but it also allows you to write tests for different configuration scenarios.
public class MyObject
{
public void Configure(MyConfigurationObject config)
{
_enabled = config.Enabled;
}
public string Foo()
{
if (_enabled)
{
return "foo!";
}
return String.Empty;
}
private bool _enabled;
}
[TestFixture]
public class MyObjectTestFixture
{
[Test]
public void CanInitializeWithProperConfig()
{
MyConfigurationObject config = new MyConfigurationObject();
config.Enabled = true;
MyObject myObj = new MyObject();
myObj.Configure(config);
Assert.AreEqual("foo!", myObj.Foo());
}
}
If you have a solution which contains for example Web Application and Test Project, you probably want that Test Project uses Web Application's web.config.
One way to solve it is to copy web.config to test project and rename it as app.config.
Another and better solution is to modify build chain and make it to make automatic copy of web.config to test projects output directory. To do that, right click Test Application and select properties. Now you should see project properties. Click "Build Events" and then click "Edit Post-build..." button. Write following line to there:
copy "$(SolutionDir)\WebApplication1\web.config" "$(ProjectDir)$(OutDir)$(TargetFileName).config"
And click OK. (Note you most probably need to change WebApplication1 as you project name which you want to test). If you have wrong path to web.config then copy fails and you will notice it during unsuccessful build.
Edit:
To Copy from the current Project to the Test Project:
copy "$(ProjectDir)bin\WebProject.dll.config" "$(SolutionDir)WebProject.Tests\bin\Debug\App.Config"
.config
files. Thanks for sharing! :)
web.config
only have references to external .config
files within the same project. As the path can only point to folders within the same directory (which is true normally), when running tests, it will not be able to handle those external files. Any idea how to solve it?
This is a bit old but I found a better solution for this. I was trying the chosen answer here but looks like .testrunconfig is already obsolete.
1. For Unit Tests, Wrap the config is an Interface (IConfig)
for Unit tests, config really shouldn't be part of what your testing so create a mock which you can inject. In this example I was using Moq.
Mock<IConfig> _configMock;
_configMock.Setup(config => config.ConfigKey).Returns("ConfigValue");
var SUT = new SUT(_configMock.Object);
2. For Integration test, dynamically add the config you need
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if(config.AppSettings.Settings[configName] != null)
{
config.AppSettings.Settings.Remove(configName);
}
config.AppSettings.Settings.Add(configName, configValue);
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("appSettings");
This is very easy.
Right click on your test project
Add-->Existing item
You can see a small arrow just beside the Add button
Select the config file click on "Add As Link"
If you are using NUnit, take a look at this post. Basically you'll need to have your app.config in the same directory as your .nunit file.
If you application is using setting such as Asp.net ConnectionString you need to add the attribute HostType to your method, else they wont load even if you have an App.Config file.
[TestMethod]
[HostType("ASP.NET")] // will load the ConnectionString from the App.Config file
public void Test() {
}
I use NUnit and in my project directory I have a copy of my App.Config that I change some configuration (example I redirect to a test database...). You need to have it in the same directory of the tested project and you will be fine.
I couldn't get any of these suggestions to work with nUnit 2.5.10 so I ended up using nUnit's Project -> Edit functionality to specify the config file to target (as others have said it needs to be in the same folder as the .nunit file itself). The positive side of this is that I can give the config file a Test.config name which makes it much clearer what it is and why it is)
https://i.stack.imgur.com/R55ng.png
https://i.stack.imgur.com/LMBYU.png
https://i.stack.imgur.com/GMWzI.png
https://i.stack.imgur.com/EqWxX.png
And finally debugged my test and value from App.config
:
https://i.stack.imgur.com/kZehh.png
Success story sharing