ChatGPT解决这个技术问题 Extra ChatGPT

Can a unit test project load the target application's app.config file?

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.


b
bbodenmiller

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


Perfect answer, simple and objective! +1
This is the best solution and should be marked as the answer.
For adding existing item "as a link" you should: "In the Add Existing Item dialog box, locate and select the project item you want to link", then: "From the Open button drop-down list, select Add As Link."
This worked great for me. I'm trying to think of a situation where it would not work... And I've thought enough now. Thanks!
J
Jeromy Irvine

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.


It's a lot easier to just add an app.config fiel to the test project -- you then don't need to play around with the .testrunconfig at all.
@Rowland if you do that, you have to maintain two copies of app.config. I'd rather spend 10 seconds, once, using the .testrunconfig tool than having to remember to update the app.config in both places.
Can't you just add a non-copying reference? (Add Existing Item...)
EFraim's comment should be the accepted answer, this is much simpler than anything else.
For EFraim's soln: Be sure to use the "Add as Link" from the command button. Otherwise you still get a copy. Also, although the question is specifically for a .Net app, this won't work for a web app as a web app's config has the wrong name (Web.Config, not App.Config)
d
dhinesh

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());
     }
}

I agree with the spirit of passing in the configuration dependency here, this seems to have been answered, by Mark Seemann no less! over here: Failing unit tests due to missing .config file
There is a " missing from the line: string value = ConfigurationManager.AppSettings["TestValue]; I tried to fix it, but would have had to find a further 5 characters to fix to get stackoverflow to allow me to make an edit.
J
Jeremy Thompson

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"

Really nice solution. This helped me avoid copying and duplicating .config files. Thanks for sharing! :)
Very nice solution! Thanks a lot.
Nice solution, but what happens when the main 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 worked for me: copy "$(SolutionDir)\MainProject\Web.config" "$(ProjectDir)app.config"
M
MichaelChan

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");

H
Hari Das

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"


C
Cory Foy

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.


I'm using VS08 Team System for my unit tests but thanks for the NUnit tip!
Z
Zyo

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() {

}

P
Patrick Desjardins

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.


J
Jane

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)


B
Ben

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