Aquí está mi granito de arena a este desafío. Simplemente, cree una nueva clase AppSettings como una capa de abstracción. En operaciones normales, simplemente leerá la configuración desde el archivo de configuración de la aplicación. Pero las pruebas unitarias pueden anular la configuración en cada subproceso, lo que permite que las pruebas unitarias se ejecuten en paralelo con diferentes configuraciones.
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;
}
En el código de aplicación, la configuración de acceso utilizando las propiedades estáticas:
function void MyApplicationMethod() {
string setting1 = AppSettings.Setting1;
string setting2 = AppSettings.Setting2;
}
En pruebas de unidad, la configuración opcionalmente anular seleccionados:
[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
}
}
Nota: Como todos los métodos de los AppSettings la clase se declara como interna, es necesario hacerla visible para el conjunto de prueba de la unidad utilizando el atributo: [assembly: InternalsVisibleTo ("< nombre de conjunto >, PublicKey = < clave pública > ")]
¿Puede explicar mejor el caso de uso? ¿Por qué necesitarías cambiar el test.dll.config en tiempo de ejecución? –
Esta es exactamente la misma pregunta que esta: http://stackoverflow.com/questions/168931/unit-testing-the-app-config-file-with-nunit –
Bien, supongo que se puede cerrar. Gracias por el puntero. – FunLovinCoder