164 votes

Un projet de test unitaire peut-il charger le fichier app.config de l'application cible ?

Je procède à des tests unitaires d'une application .NET (.exe) qui utilise un fichier app.config pour charger les propriétés de configuration. L'application de test unitaire elle-même n'a pas de fichier app.config.

Lorsque j'essaie de tester une méthode qui utilise l'une des propriétés de la configuration, elle renvoie la réponse suivante null . Je suppose que c'est parce que l'application de test unitaire ne va pas se charger dans l'app.config de l'application cible.

Existe-t-il un moyen de passer outre ou dois-je écrire un script pour copier le contenu de l'app.config cible vers un app.config local ?

Ce site Ce post pose en quelque sorte cette question, mais l'auteur l'aborde sous un angle différent du mien.

EDIT : Je dois mentionner que j'utilise VS08 Team System pour mes tests unitaires.

125voto

Dans Visual Studio 2008, j'ai ajouté l'élément app.config dans le projet de test en tant qu'élément existant et sélectionné copier comme lien afin de s'assurer qu'il n'est pas dupliqué. De cette façon, je n'ai qu'une seule copie dans ma solution. Avec plusieurs projets de test, c'est vraiment pratique !

Add Existing Item

Add As Link

64voto

Jeromy Irvine Points 5308

La façon la plus simple de procéder est d'ajouter l'option .config dans la section de déploiement de votre test unitaire.

Pour ce faire, ouvrez le .testrunconfig de vos éléments de solution. Dans la section Déploiement, ajoutez la sortie .config du répertoire de construction de votre projet (vraisemblablement bin\Debug ).

Tout ce qui est listé dans la section de déploiement sera copié dans le dossier de travail du projet de test avant que les tests ne soient exécutés, donc votre code dépendant de la configuration fonctionnera bien.

Edit : J'ai oublié d'ajouter, ceci ne fonctionnera pas dans toutes les situations, donc vous devrez peut-être inclure un script de démarrage qui renomme la sortie .config pour correspondre au nom du test unitaire.

9 votes

Il est beaucoup plus facile d'ajouter un champ app.config au projet de test -- vous n'avez alors pas besoin de jouer avec le .testrunconfig du tout.

13 votes

@Rowland si vous faites cela, vous devez maintenir deux copies de app.config. Je préfère passer 10 secondes, une seule fois, à utiliser l'outil .testrunconfig plutôt que de devoir me souvenir de mettre à jour l'app.config aux deux endroits.

71 votes

Ne pouvez-vous pas simplement ajouter une référence non copiante ? (Ajouter un élément existant...)

55voto

bryanbcook Points 7184

Que vous utilisiez Test du système de l'équipe o NUnit Pour les tests, la meilleure pratique consiste à créer une bibliothèque de classes distincte pour vos tests. Il suffit d'ajouter un App.config à votre projet de test pour qu'il soit automatiquement copié dans votre dossier bin lors de la compilation. .

Si votre code dépend de tests de configuration spécifiques, le tout premier test que j'écrirais validerait que le fichier de configuration est disponible ( pour que je sache que je ne suis pas fou. ) :

<configuration>
   <appSettings>
       <add key="TestValue" value="true" />
   </appSettings>
</configuration>

Et le test :

[TestFixture]
public class GeneralFixture
{
     [Test]
     public void VerifyAppDomainHasConfigurationSettings()
     {
          string value = ConfigurationManager.AppSettings["TestValue"];
          Assert.IsFalse(String.IsNullOrEmpty(value), "No App.Config found.");
     }
}

Idéalement, vous devriez écrire du code de telle sorte que vos objets de configuration soient passés dans vos classes. Cela permet non seulement de s'affranchir du problème des fichiers de configuration, mais aussi d'écrire des tests pour différents scénarios de configuration.

public class MyObject
{
     public void Configure(MyConfigurationObject config)
     {
          _enabled = config.Enabled;
     }

     public string Foo()
     {
         if (_enabled)
         {
             return "foo!";
         }
         return String.Empty;
     }

     private bool _enabled;
}

[TestFixture]
public class MyObjectTestFixture
{
     [Test]
     public void CanInitializeWithProperConfig()
     {
         MyConfigurationObject config = new MyConfigurationObject();
         config.Enabled = true;

         MyObject myObj = new MyObject();
         myObj.Configure(config);

         Assert.AreEqual("foo!", myObj.Foo());
     }
}

2 votes

Je suis d'accord avec l'esprit de passer dans la dépendance de la configuration ici, cela semble avoir été répondu, par Mark Seemann pas moins ! ici : Échec des tests unitaires en raison de l'absence de fichier .config

0 votes

Il manque un " dans la ligne : string value = ConfigurationManager.AppSettings["TestValue] ; J'ai essayé de le corriger, mais il aurait fallu trouver 5 autres caractères à corriger pour que stackoverflow me permette de faire une modification.

24voto

Antti Points 81

Si vous avez une solution qui contient par exemple une application Web et un projet de test, vous voulez probablement que le projet de test utilise le web.config de l'application Web.

Une façon de résoudre ce problème est de copier web.config dans le projet de test et de le renommer en app.config.

Une autre solution, plus efficace, consiste à modifier la chaîne de construction pour qu'elle effectue une copie automatique du fichier web.config dans le répertoire de sortie des projets de test. Pour ce faire, faites un clic droit sur l'application de test et sélectionnez les propriétés. Vous devriez maintenant voir les propriétés du projet. Cliquez sur "Build Events" et ensuite sur le bouton "Edit Post-build...". Écrivez la ligne suivante à cet endroit :

copy "$(SolutionDir)\WebApplication1\web.config" "$(ProjectDir)$(OutDir)$(TargetFileName).config"

Et cliquez sur OK. (Notez que vous devrez probablement changer WebApplication1 comme nom du projet que vous voulez tester). Si le chemin d'accès au fichier web.config est incorrect, la copie échoue et vous le remarquerez lors de l'échec de la construction.

Edit :

Pour copier du projet actuel au projet de test :

copy "$(ProjectDir)bin\WebProject.dll.config" "$(SolutionDir)WebProject.Tests\bin\Debug\App.Config"

0 votes

Une solution très agréable. Cela m'a permis d'éviter de copier et de dupliquer. .config fichiers. Merci pour le partage ! :)

0 votes

Très belle solution ! Merci beaucoup.

0 votes

Belle solution, mais que se passe-t-il lorsque le principal web.config n'ont que des références à des .config dans le même projet. Comme le chemin d'accès ne peut pointer que vers les dossiers du même répertoire (ce qui est vrai normalement), lors de l'exécution des tests, il ne sera pas en mesure de gérer ces fichiers externes. Une idée pour résoudre ce problème ?

10voto

MichaelChan Points 1106

C'est un peu vieux mais j'ai trouvé une meilleure solution pour cela. J'ai essayé la réponse choisie ici mais il semble que .testrunconfig soit déjà obsolète.

1. Pour les tests unitaires, la configuration est une interface (IConfig).

pour les tests unitaires, la configuration ne devrait pas faire partie de ce que vous testez, alors créez un simulateur que vous pouvez injecter. Dans cet exemple, j'ai utilisé Moq.

Mock<IConfig> _configMock;
_configMock.Setup(config => config.ConfigKey).Returns("ConfigValue");
var SUT = new SUT(_configMock.Object);

2. Pour le test d'intégration, ajoutez dynamiquement la configuration dont vous avez besoin.

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if(config.AppSettings.Settings[configName] != null)
{
    config.AppSettings.Settings.Remove(configName);
}
config.AppSettings.Settings.Add(configName, configValue);
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("appSettings");

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X