.net - test - Unidad probando el archivo app.config con NUnit
unit test.net core (13)
¿Cuándo están probando las unidades de una aplicación que se basa en los 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?
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 ConfigurationManager no pueda leer los valores, pero me preocupa comprobar cómo reacciona mi programa a los valores que se leen.
Bueno, acabo de tener el mismo problema ... Quería probar un proyecto BL que se hace referencia desde un sitio web. pero quería probar solo el BL. 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 app.config ...
En realidad, pensando en ello aún más, supongo que lo que debería hacer es crear una 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?
Eso funcionó 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);
}
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 pregunte por tal-y- tal valor de appSettings, devuelve este valor conocido ".
Me enfrentaba a problemas similares con web.config ... Encuentro una solución interesante. Puede encapsular la función de lectura de configuración, por ejemplo, algo como esto:
public class MyClass {
public static Func<string, string>
GetConfigValue = s => ConfigurationManager.AppSettings[s];
//...
}
Y luego normalmente usa
string connectionString = MyClass.GetConfigValue("myConfigValue");
pero en la prueba unitaria inicializa "anula" la función de esta manera:
MyClass.GetConfigValue = s => s == "myConfigValue" ? "Hi", "string.Empty";
Más sobre esto:
http://rogeralsing.com/2009/05/07/the-simplest-form-of-configurable-dependency-injection/
Normalmente aislo 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 forma, puede probar fácilmente su código con diferentes valores de configuración sin escribir pruebas complejas que primero escriban archivos de configuración xml. El código que lee la configuración suele ser tan simple que requiere muy pocas pruebas.
Puede leer y escribir en el archivo app.config
con la clase ConfigurationManager
Puede llamar al método set de ConfigurationManager.AppSettings para establecer los valores necesarios para esa prueba particular de la unidad.
[SetUp]
public void SetUp()
{
ConfigurationManager.AppSettings.Set("SettingKey" , "SettingValue");
// rest of unit test code follows
}
Cuando se ejecuta la prueba unitaria, usará estos valores para ejecutar el código
Puede modificar su sección de configuración en tiempo de ejecución en la configuración de prueba. P.ej:
// 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 ...
Por supuesto, puede configurar sus propios métodos de ayuda para hacerlo de forma más elegante.
Siempre puede ajustar el bit de lectura en una interfaz y tener una lectura de implementación específica 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 estoy asumiendo, afortunadamente, que la MS ya lo ha probado).
System.Configuration.Abstractions es algo maravilloso cuando se trata de probar este tipo de cosas.
Aquí está el sitio del proyecto GitHub con algunos buenos ejemplos: ingrese la descripción del enlace aquí
Aquí está el sitio NuGet: https://www.nuget.org/packages/System.Configuration.Abstractions/
Uso esto en casi todos mis proyectos .NET.
Tuve el mismo problema,
puede usar Nunit-console.exe c: / path1 / testdll1.dll c: / path2 / testdll2.dll
esto funciona bien aunque ambos dlls apuntan a diferentes app.configs ex testdll1.dll.config y testdll2.dll.config
si desea utilizar la configuración del proyecto Nunit y ajustar estos dos archivos DLL, entonces no hay manera de que pueda tener dos configuraciones
tienes que tener project1.config si tu proyecto Nunit es project1.nunit en la misma ubicación que Project1.nunit.
espero que esto ayude
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 clase de configuración de lectura / envoltura, etc.
Por ejemplo, supongamos que una clase "Clima" requiere un "ServiceUrl" 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 puede luego inyectarse utilizando un contenedor de Inversión de control (o Inyección de dependencia), por lo que los consumidores de la clase Tiempo no necesitan proporcionar explícitamente el valor de algún lugar, ya que es manejado por el contenedor.