Manipulating the app.config file for unit tests

I isolated the NUnit tests for my C # application in an assembly called Tests.dll. The associated configuration file is called Tests.dll.config. This is what Nunit uses, not the actual configuration file of my application. It seems like this (only displaying multiple configuration options there are many more):

<?xml version="1.0" encoding="utf-8"?>

<configuration>
  <appSettings>
    <add key="useHostsFile" value="true" />
    <add key="importFile" value="true" />

   </appSettings>
</configuration>

In order for my application to be thoroughly tested, I will need to change the configuration settings between tests. After I conduct a couple of tests, I would like to add new configuration values ​​to the file and use them for subsequent tests. What code will I need to add?

+5
source share
3 answers

IConfig useHostsFile importFile. , ConfigDefault, IConfig. . , IConfig. Dependecy Injection. Ninject .

+3

:

 [TestMethod]
    public void Test_general()
    {
        var cs = new ConnectionStringSettings();
        cs.Name = "ConnectionStrings.Oracle";
        cs.ConnectionString = "DATA SOURCE=xxx;PASSWORD=xxx;PERSIST SECURITY INFO=True;USER ID=xxx";
        cs.ProviderName = "Oracle.DataAccess.Client";

        var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        //config.ConnectionStrings.ConnectionStrings.Clear();
        config.ConnectionStrings.ConnectionStrings.Remove(cs.Name);
        config.ConnectionStrings.ConnectionStrings.Add(cs);
        config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection("connectionStrings");

        // your code for your test here
   }
0

. AppSettings . . , .

internal sealed class AppSettings
{
    private static readonly AppSettings instance;
    private static ConcurrentDictionary<int, AppSettings> threadInstances;
    private string _setting1;
    private string _setting2;

    static AppSettings() { instance = new AppSettings(); }

    internal AppSettings(string setting1 = null, string setting2 = null) {
        _setting1 = setting1 != null ? setting1 : Properties.Settings.Default.Setting1;
        _setting2 = setting2 != null ? setting2 : Properties.Settings.Default.Setting2;
    }

    internal static AppSettings Instance {
        get {
            if (threadInstances != null) {
                AppSettings threadInstance;
                if (threadedInstances.TryGetValue(Thread.CurrentThread.ManagedThreadId, out threadInstance)) {
                    return threadInstance;
                }
            }
            return instance;
        }

        set {
            if (threadInstances == null) {
                lock (instance) {
                    if (threadInstances == null) {
                        int numProcs = Environment.ProcessorCount;
                        int concurrencyLevel = numProcs * 2;
                        threadInstances = new ConcurrentDictionary<int, AppSettings>(concurrencyLevel, 5);
                    }
                }
            }

            if (value != null) {
                threadInstances.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, value, (key, oldValue) => value);
            } else {
                AppSettings threadInstance;
                threadInstances.TryRemove(Thread.CurrentThread.ManagedThreadId, out threadInstance);
            }
        }
    }

    internal static string Setting1 => Instance._setting1;

    internal static string Setting2 => Instance._setting2;
}

, :

function void MyApplicationMethod() {
    string setting1 = AppSettings.Setting1;
    string setting2 = AppSettings.Setting2;
}

In unit tests, it is possible to override the selected settings:

[TestClass]
public class MyUnitTest
{
    [TestCleanup]
    public void CleanupTest()
    {
        //
        // Clear any app settings that were applied for the current test runner thread.
        //
        AppSettings.Instance = null;
    }

    [TestMethod]
    public void MyUnitMethod()
    {
        AppSettings.Instance = new AppSettings(setting1: "New settings value for current thread");
        // Your test code goes here
    }
}

NOTE. Since all methods of the AppSettings class are declared internal, you must make them visible to the unit test assembly using the attribute: [assembly: InternalsVisibleTo ("<assembly name>, PublicKey = <public key>")]

0
source

All Articles