Question

Quand vous testez une application qui repose sur les valeurs d’un fichier app.config? Comment vérifier que ces valeurs sont lues correctement et comment votre programme réagit aux valeurs incorrectes entrées dans un fichier de configuration?

Il serait ridicule de devoir modifier le fichier de configuration de l'application NUnit, mais je ne peux pas lire les valeurs du fichier app.config que je souhaite tester.

Edit: Je pense que je devrais peut-être clarifier. Je ne m'inquiète pas de l'échec de ConfigurationManager à lire les valeurs, mais je suis préoccupé par le fait de tester la réaction de mon programme aux valeurs lues.

Était-ce utile?

La solution

J'isole généralement les dépendances externes, telles que la lecture d'un fichier de configuration dans leur propre classe de façade avec très peu de fonctionnalités. Dans les tests, je peux créer une version fictive de cette classe qui l'implémente et l'utiliser à la place du fichier de configuration réel. Vous pouvez créer vos propres maquettes ou utiliser un framework tel que moq ou rhino mock pour cela.

De cette façon, vous pouvez facilement essayer votre code avec différentes valeurs de configuration sans écrire de tests complexes qui écrivent d’abord des fichiers de configuration XML. Le code qui lit la configuration est généralement si simple qu’il nécessite très peu de tests.

Autres conseils

Vous pouvez modifier votre section de configuration au moment de l'exécution dans votre configuration de test. E.g:

// 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 ...

Vous pouvez bien sûr configurer vos propres méthodes d'assistance pour le faire de manière plus élégante.

Vous pouvez appeler la méthode set de ConfigurationManager.AppSettings pour définir les valeurs requises pour ce test d'unité particulier.

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

Lorsque le test unitaire est exécuté, il utilisera ces valeurs pour exécuter le code

Vous pouvez lire et écrire dans le fichier app.config avec la classe ConfigurationManager

.

Je rencontrais des problèmes similaires avec web.config .... Je trouve une solution intéressante. Vous pouvez encapsuler une fonction de lecture de la configuration, par exemple quelque chose comme ceci:

public class MyClass {

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

//...

}

Et ensuite, utilisez normalement

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

mais dans le test unitaire initialisez " override " la fonction comme ceci:

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

Pour en savoir plus:

http: // rogeralsing. com / 2009/05/07 / la forme la plus simple d'injection de dépendance configurable /

Une solution plus élégante consiste à utiliser une simple injection de dépendance ancienne sur les paramètres de configuration eux-mêmes. IMHO c'est plus propre que d'avoir à se moquer d'une classe de lecture de configuration / wrapper, etc.

Par exemple, dites une classe " Météo " nécessite un " ServiceUrl " pour pouvoir fonctionner (par exemple, il appelle un service Web pour obtenir la météo). Plutôt que d'avoir une ligne de code qui va activement dans un fichier de configuration pour obtenir ce paramètre (que ce code soit dans la classe Weather ou un lecteur de configuration séparé qui pourrait être simulé comme dans d'autres réponses), la classe Weather peut permettre le paramétrage à injecter, soit via un paramètre au constructeur, soit éventuellement via un configurateur de propriétés. De cette façon, les tests unitaires sont extrêmement simples et directs, et ne nécessitent même pas de se moquer.

La valeur du paramètre peut ensuite être injectée à l'aide d'un conteneur Inversion of Control (ou Dependency Injection), afin que les utilisateurs de la classe Weather ne soient pas obligés de fournir explicitement la valeur quelque part, car elle est gérée par le conteneur.

Cela a fonctionné pour moi:

 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);
  }

Vous pouvez toujours envelopper le bit de lecture dans une interface et faire lire une implémentation spécifique à partir du fichier de configuration. Vous écririez ensuite des tests à l'aide de Mock Objects pour voir comment le programme traitait les mauvaises valeurs. Personnellement, je ne testerais pas cette implémentation spécifique, car il s’agit d’un code .NET Framework (et je suppose, espérons-le, que le MS l’a déjà testé).

System.Configuration.Abstractions est une chose de beauté quand il s'agit de tester ce genre de choses.

Voici le site du projet GitHub avec quelques bons exemples: entrez la description du lien ici

Voici le site NuGet: https://www.nuget.org/packages /System.Configuration.Abstractions/

Je l'utilise dans presque tous mes projets .NET.

En fait, en y réfléchissant un peu plus loin, je suppose que ce que je devrais faire, c'est créer une classe ConfigFileReader à utiliser dans mon projet, puis la simuler dans le faisceau de tests unitaires?

Est-ce la chose habituelle à faire?

L'option la plus simple consiste à encapsuler les méthodes de lecture de la configuration de manière à pouvoir les remplacer par des valeurs lors des tests. Créez une interface que vous utilisez pour lire config et faites en sorte qu'une implémentation de cette interface soit transmise en tant que paramètre de constructeur ou définie sur l'objet en tant que propriété (comme vous le feriez avec l'injection / inversion de contrôle de dépendance). Dans l'environnement de production, transmettez une implémentation qui lit réellement à partir de la configuration; dans l'environnement de test, transmettez une implémentation de test qui renvoie une valeur connue.

Si vous n'avez pas la possibilité de refactoriser le code à des fins de testabilité mais que vous ayez encore besoin de le tester, Typemock Isolator permet de simuler les classes de configuration du framework .NET afin que vous puissiez simplement dire "la prochaine fois que je le demanderai. telle ou telle valeur appSettings, renvoie cette valeur connue. "

J'ai eu le même problème,

vous pouvez utiliser Nunit-console.exe c: \ path1 \ testdll1.dll c: \ path2 \ testdll2.dll

cela fonctionne bien même si les deux dll pointent vers des applications différentes. ex testdll1.dll.config et testdll2.dll.config

si vous voulez utiliser la configuration de projet Nunit et envelopper ces deux dll, il n’ya aucun moyen d’avoir deux configurations

vous devez avoir project1.config si votre projet Nunit est project1.nunit au même endroit que Project1.nunit.

espérons que cela aide

Eh bien, je viens d'avoir le même problème ... Je voulais tester un projet BL référencé depuis un site Web. mais je voulais tester le BL uniquement. Donc, dans l'événement de pré-construction du projet de test, je copie les fichiers app.Config dans le dossier bin \ debug et les référence depuis le fichier app.config ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top