2008-10-03 20 views
57

¿Cuándo están probando unidades una aplicación que se basa en valores de un archivo app.config? ¿Cómo se prueba que esos valores se leen correctamente y cómo reacciona su programa a los valores incorrectos ingresados ​​en un archivo de configuración?Unidad probando el archivo app.config con NUnit

Sería ridículo tener que modificar el archivo de configuración para la aplicación NUnit, pero no puedo leer los valores de la aplicación.config que quiero probar.

Editar: Creo que debería aclarar tal vez. No me preocupa que el ConfigurationManager no pueda leer los valores, pero me preocupa probar cómo mi programa reacciona a los valores leídos.

Respuesta

41

Normalmente aíslo dependencias externas como leer un archivo de configuración en su propia clase de fachada con muy poca funcionalidad. En las pruebas, puedo crear una versión simulada de esta clase que implemente y use eso en lugar del archivo de configuración real. Puede crear su propia maqueta o utilizar un marco como moq o rhino mocks para esto.

De esta manera puede probar fácilmente su código con diferentes valores de configuración sin escribir pruebas complejas que primero escriben archivos de configuración xml. El código que lee la configuración suele ser tan simple que requiere muy pocas pruebas.

+3

Es aterrador ver que esta respuesta no tiene más votos ascendentes y que otras respuestas que hablan de agregar/leer/editar archivos de configuración tienen tantos puntos. Para los lectores, esta es la mejor forma de seguir y mantener sus pruebas unitarias simples y SÓLIDAS. –

+0

"No hay problema que no pueda resolverse agregando otra capa de abstracción". :-) – Iain

0

En realidad, pensando en ello aún más, supongo que lo que debería hacer es crear un La clase ConfigFileReader para usar en mi proyecto y luego falsificarlo en el arnés de prueba de la unidad?

¿Es eso lo que se suele hacer?

16

Puede leer y escribir en el fichero app.config con la clase ConfigurationManager

+2

Ahhh, entonces puedo establecer valores en la colección ConfigurationManager? Siempre asumí que era de solo lectura. Supongo que eso es lo que obtengo para hacer suposiciones: P – Dana

+3

¡Acabo de probar esto, y funciona genial! Por ejemplo, 'ConfigurationManager.AppSettings [" SomeKey "] =" MockValue ";'. ¡Buena respuesta! –

+0

Cuando lo probé cambia el valor de la clave u especifica pero también elimina valores y todas las otras claves :( – Yasser

1

Siempre se puede ajustar el bit de lectura-in en una interfaz, y tienen una aplicación específica leer desde el archivo de configuración. Luego, escribiría pruebas utilizando Objetos simulados para ver cómo el programa manejaba los valores incorrectos. Personalmente, no probaría esta implementación específica, ya que este es el código de .NET Framework (y asumo que, con suerte, la MS ya lo ha probado).

0

La opción más simple es ajustar los métodos que leen la configuración de modo que pueda sustituirlos en valores durante la prueba. Cree una interfaz que use para leer config y haga pasar una implementación de esa interfaz como un parámetro constructor o establezca el objeto como una propiedad (como lo haría usando la inyección de dependencia/inversión de control). En el entorno de producción, pase una implementación que realmente lea desde la configuración; en el entorno de prueba, pase una implementación de prueba que devuelva un valor conocido.

Si no tiene la opción de refactorizar el código para probarlo y todavía necesita probarlo, Typemock Isolator proporciona la capacidad de simular realmente las clases de configuración de .NET framework para que pueda decir "la próxima vez que pida tal y como valor de appSettings, devuelva este valor conocido ".

0

que tenían el mismo problema,

puede utilizar Nunit-console.exe c: \ rutaDeAcceso1 \ testdll1.dll c: \ via2 \ testdll2.dll

esto funciona bien a pesar de que si los dos archivos DLL punto a diferentes app.configs ex testdll1.dll.config y testdll2.dll.config

si desea utilizar Nunit configuración del proyecto y envolver estos dos archivos DLL, entonces no hay manera que usted puede tener dos configuraciones

tienes que tener project1.config si su proyecto Nunit es project1.nunit en la misma ubicación que Project1.nunit.

espero que esta ayuda

29

Puede modificar la sección de configuración en tiempo de ejecución en la configuración de prueba. Por ejemplo:

// setup 
System.Configuration.Configuration config = 
    ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
config.Sections.Add("sectionname", new ConfigSectionType()); 
ConfigSectionType section = (ConfigSectionType)config.GetSection("sectionname"); 
section.SomeProperty = "value_you_want_to_test_with"; 
config.Save(ConfigurationSaveMode.Modified); 
ConfigurationManager.RefreshSection("sectionname"); 

// carry out test ... 

Puede, por supuesto, configurar sus propios métodos de ayuda para hacerlo de forma más elegante.

+0

La lectura de un archivo del disco hace que todo el conjunto de pruebas se convierta en pruebas de integración. Ya no se realizan pruebas unitarias ya que se usan dependencias globales estatales y externas. – kai

11

Estaba enfrentando problemas similares con web.config .... Encuentro una solución interesante. Puede encapsular la función de lectura de configuración, p. algo como esto:

public class MyClass { 

public static Func<string, string> 
    GetConfigValue = s => ConfigurationManager.AppSettings[s]; 

//... 

} 

y luego usar normalmente

string connectionString = MyClass.GetConfigValue("myConfigValue"); 

pero en prueba de la unidad inicializar "anular" la función de la siguiente manera:

MyClass.GetConfigValue = s => s == "myConfigValue" ? "Hi", "string.Empty"; 

más sobre él:

http://rogeralsing.com/2009/05/07/the-simplest-form-of-configurable-dependency-injection/

3

Una solución más elegante es usar una antigua inyección de dependencia simple en la configuración de configuración. En mi humilde opinión esto es más limpio que tener que burlarse de una configuración de clase de lectura/envoltura, etc.

Por ejemplo, supongamos que una clase "Meteorología" requiere un "ServicioUrl" para funcionar (por ejemplo, decir que llama a un servicio web para obtener el clima) En lugar de tener alguna línea de código que va activamente a un archivo de configuración para obtener esa configuración (ya sea que esté en la clase Weather o un lector de configuración diferente que pueda ser burlado según algunas de las otras respuestas), la clase Weather puede permitir la configuración que se inyectará, ya sea a través de un parámetro para el constructor, o posiblemente a través de un ajustador de propiedades. De esta forma, las pruebas unitarias son extremadamente simples y directas, y ni siquiera requieren burlas.

El valor de la configuración se puede inyectar utilizando un contenedor de Inversión de control (o Inyección de dependencia), por lo que los consumidores de la clase Weather no necesitan proporcionar explícitamente el valor de alguna parte, ya que es manejado por el contenedor .

2

que trabajó para mí:

public static void BasicSetup() 
    { 
    ConnectionStringSettings connectionStringSettings = 
      new ConnectionStringSettings(); 
    connectionStringSettings.Name = "testmasterconnection"; 
    connectionStringSettings.ConnectionString = 
      "server=localhost;user=some;database=some;port=3306;"; 
    ConfigurationManager.ConnectionStrings.Clear(); 
    ConfigurationManager.ConnectionStrings.Add(connectionStringSettings); 
    } 
20

Usted puede llamar al método conjunto de ConfigurationManager.AppSettings para establecer los valores necesarios para que la prueba de la unidad en particular.

[SetUp] 
public void SetUp() 
{ 
    ConfigurationManager.AppSettings.Set("SettingKey" , "SettingValue"); 
    // rest of unit test code follows 
} 

Cuando se ejecuta la prueba unitaria será entonces utilizar estos valores para ejecutar el código

+2

Esta fue de lejos la forma más fácil de resolverlo para mis propósitos. Mi código simplemente comprobó si la clave llamada Entorno era TEST o LIVE. Así que simplemente configuro la clave para TEST al comienzo del método de prueba de la unidad. –

0

Bueno, acabo de tener el mismo problema ... que quería probar un proyecto BL que se hace referencia a partir de una sitio web pero yo quería probar el BL solamente. Por lo tanto, en el evento de preconstrucción del proyecto de prueba, copio la aplicación. Configuro archivos en la carpeta bin \ debug y los menciono desde la aplicación.config ...

Cuestiones relacionadas