9

I want to do some unit testing on one of my projects. This is a web project, and there will only be one copy of this program running aside from development copies.

I want to write some unit tests that will use the web.config. I understand that ordinarily, a tester would stub out this external dependency because he wants to test the code without the test depending on the web.config holding certain values.

However, the web.config in my project is supposed to always hold certain values and I want to have a unit test that will fail if they are set to invalid values. For example, one of the values is a SQL connection string.

I want to write a test that will read the connection string from the web.config. I envision that the test could connect to a server with the connection string and perhaps perform a very simple command like SELECT system_user;. If the command executes successfully and returns something the test passes. Otherwise, it fails. I want the connection string to be read from the web.config in the project I'm testing.

Of course, the ConfigurationManager will not ordinarily look for a web.config in another project. I could manually copy the web.config from the original project to the test project, but I would have to do that before every test and there is no way I could count on anyone else to do that.

How do I make my test project read the web.config from another project?

Vivian River
  • 28,530
  • 54
  • 179
  • 298
  • 2
    There's a better way than copying the config to the test project, goto add existing item and select the web.config instead of clicking the add button click the arrow next to it and choose as a link. Now your test project has the live copy of the web.config as a symbolic link. – Chris Marisic Mar 05 '10 at 17:50
  • Chris, I tried your suggestion and just as I suspected, it makes a copy of the file in the directory for the unit test project; that's what I wanted to avoid. – Vivian River Mar 05 '10 at 17:54
  • What is your end game here? The "So That..." portion of your use case. You may be putting a lot of effort into testing something that is completley superfluous because it doesn't buy you any confidence. The config file is dynamic by it's very nature, and updating it may be a requirement on the fly. However you tests would now fail because they were expecting some value. Perhaps if you could explain "Why" you are doing this, we could better help to devise a plan for testing. – Josh Mar 05 '10 at 18:00
  • Yes, Josh, the `web.config` file is dynamic. However, there will only be a single instance of this application running in production. I wish to have a unit test that retrieves a connection string from the `web.config` and verifies that it is valid. Yes, the `web.config` is technically dynamic, but in practice, it won't be changing once it's deployed. – Vivian River Mar 05 '10 at 18:34
  • 1
    It does not make a copy of the config, it creates a symbolic link. This means your test project sees the file exactly as if it was there but it doesn't physically exist in the project. (it does however become copied to the build directory upon compilation) – Chris Marisic Mar 05 '10 at 18:42
  • Thanks Chris, I see that I missed the "add as link part" – Vivian River Mar 11 '10 at 18:03

7 Answers7

4

It sounds like you are trying to validate settings in web.config, which is a deployment-level concern and is different from unit testing.

Unit testing tells you that your core logic is performing as expected; deployment verification tells you that the application was installed and configured properly and is safe to use. Unit tests are meaningful to developers, deployment verification is meaningful to the end user or administrator that is deploying the app.

In situation like this I like to build a "system console" into my apps. This console contains a number of self-diagnostic checks such as:

  1. Ensuring the connection string(s) are configured properly
  2. Ensuring that any 3rd party services are available and functioning
  3. Ensuring that all configuration settings are valid and won't cause runtime errors (e.g. paths exist, the web user account has read/write access where needed, etc)

I strongly recommend you consider separating this sort of configuration and deployment verification from your unit test suite. Not only will it simplify your work (because you won't have to load a config file from another project) but it's also the sort of tool that customers really, really like :)

Seth Petry-Johnson
  • 11,227
  • 6
  • 44
  • 68
  • I believe that your "console" idea would make sense if this were to be a WinForms application, but being the case that this is a web application and there is only a single deployment of it, I feel that `web.config` is just as much a part of the project as any of its code files. That's why I wish to be able to test it with a connection string retrieved from `web.config` just as if it were retrieved at run-time. – Vivian River Mar 05 '10 at 18:25
  • 1
    @Rising Star: I've done this for a number of "single deployment" sites. My point is that it doesn't matter how many deployments there are, validating the deployment configuration is something that should be done _from that deployment's point of view_. If you are NOT trying to validate the deployment, but instead just want to use the web.config's connection string in your tests, could you utilize a post-build script or something that will update your test project's app.config whenever the web site is rebuilt? – Seth Petry-Johnson Mar 05 '10 at 18:34
  • I thought about writing a batch file to copy `web.config` to the test project, but I realize that then there is the issue of having the check out web.config in the test project before running tests... I may look in to this. My supervisor desires this to be a unit test in part because it's easy to run the tests as part of a build. That way, we would know when the nightly build executes that someone set an invalid connection string in web.config – Vivian River Mar 05 '10 at 18:40
  • I would not agree with that. Most of the web.config settings can be set in code instead of config as they rarely change. The only purpose of leaving them in web.config is readability of the project. From this viewpoint portions of web.config are equivalent to code. Thus they should be tested. – Anton Krouglov Jul 05 '17 at 09:58
3

You can load and explore other config files with the ConfigurationManager.OpenXXX() methods.

The WebConfigurationManager class specifically has a method for opening web.config files, and the documentation page I linked to has some more code examples. Once you have your configuration object loaded, you can explore it for sections and keys.

var cfm = new ConfigurationFileMap("path/to/web.config");
var config = WebConfigurationManager.OpenMappedWebConfiguration(cfm);
zvolkov
  • 17,762
  • 8
  • 65
  • 78
womp
  • 111,854
  • 24
  • 229
  • 262
  • I've seen something similar to your solution before. However, the issue here is that I need a constant, absolute path to the `web.config`. It throws exception if I try to use a relative path – Vivian River Mar 05 '10 at 18:24
1

There is a commercial tool called CheckMyConfig for validating .NET config files, which identifies settings within a given config file, and attempts to validate them.

Possible setting types include database connection strings, files, folders, IP addresses, hostnames and URLs.

The tool allows you to perform a number of checks including opening database connections, accessing folders, requesting a particular URL etc.

There is a standalone version, but the tool also has Visual Studio integration and a simple API that you can use to embed the tool within your own apps, in order to perform a config 'sanity check' at app startup time.

Mohit Jain
  • 29,414
  • 8
  • 65
  • 93
fawltster
  • 11
  • 1
  • Code formatting is for code. Tool names, framework names, quoted phrases *really* should not get code formatting. – mdahlman May 07 '14 at 06:50
1

I asked a similar question that you might want to check out:

How do I test that all my expected web.config settings have been defined?

I ended up getting it working but the annoying part is my source control constantly locking the config file that is copied over. You can also rename the web.config to app.config so that it will compile into a non-web project.

Community
  • 1
  • 1
Kelsey
  • 45,595
  • 16
  • 119
  • 161
1

It sounds like you're trying to squash a mosquito with a sledgehammer. Why not do this manually, as part of the deployment checklist; have a task to manually confirm the connectionString.

Or if you want to automate it, write a program to check the connectionString, attach it to your Continuous Integration server (assuming you have one) and fail the build if the connectionString is wrong.

Use Unit Tests for what they're intended for testing code, not configuration.

Gavin Miller
  • 40,636
  • 19
  • 113
  • 178
1

If you want to use original web.config file from your website to your Unit Testing project without copying it then you can Modify VS Local-Test-Settings.

Here is a step by step procedure to use ASP.net website configuration file under Unit Testing project. Follow the link http://forums.asp.net/t/1454799.aspx/1

Nishant Kumar
  • 870
  • 1
  • 8
  • 10
0

In your unit testing project, add an app.config file and add the settings from the web.config file that you would like to use for your tests.

bkaid
  • 49,467
  • 20
  • 108
  • 126