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

151

Je teste en unité 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 unitaire une méthode qui utilise l'une des propriétés de configuration, elles retournent null . Je suppose que c'est parce que l'application de test unitaire ne va pas se charger dans le app.config de l'application cible.

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

Ce message pose en quelque sorte cette question mais l'auteur la regarde vraiment sous un angle différent de celui que je suis.

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

Jordan Parmer
la source

Réponses:

59

Le moyen le plus simple de procéder consiste à ajouter le .configfichier dans la section de déploiement de votre test unitaire.

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

Tout ce qui est répertorié dans la section de déploiement sera copié dans le dossier de travail du projet de test avant l'exécution des tests, de sorte que votre code dépendant de la configuration fonctionnera correctement.

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

Jeromy Irvine
la source
9
Il est beaucoup plus facile d'ajouter simplement un champ app.config au projet de test - vous n'avez alors pas besoin de jouer du tout avec le .testrunconfig.
Rowland Shaw
13
@Rowland si vous faites cela, vous devez conserver deux copies de app.config. Je préfère passer 10 secondes, une fois, à utiliser l'outil .testrunconfig plutôt que de me souvenir de mettre à jour app.config aux deux endroits.
Jeromy Irvine
66
Ne pouvez-vous pas simplement ajouter une référence sans copie? (Ajouter un élément existant ...)
EFraim
6
Le commentaire d'EFraim devrait être la réponse acceptée, c'est beaucoup plus simple qu'autre chose.
reggaeguitar
28
Pour la solution d'EFraim: assurez-vous d'utiliser le "Ajouter comme lien" du bouton de commande. Sinon, vous en obtenez toujours une copie. De plus, bien que la question concerne spécifiquement une application .Net, cela ne fonctionnera pas pour une application Web car la configuration d'une application Web a le mauvais nom (Web.Config, pas App.Config)
Rob Von Nesselrode
104

Dans Visual Studio 2008, j'ai ajouté le app.configfichier au projet de test en tant qu'élément existant et sélectionné la copie en tant que lien afin de m'assurer qu'il n'est pas dupliqué. De cette façon, je n'ai qu'un seul exemplaire dans ma solution. Avec plusieurs projets de test, c'est vraiment pratique!

Ajouter un élément existant

Ajouter comme lien

bbodenmiller
la source
7
Réponse parfaite, simple et objective! +1
Custodio
2
C'est la meilleure solution et devrait être marquée comme la réponse.
niaher
4
Pour ajouter un élément existant "en tant que lien", vous devez: "Dans la boîte de dialogue Ajouter un élément existant, recherchez et sélectionnez l'élément de projet que vous souhaitez lier", puis: "Dans la liste déroulante du bouton Ouvrir, sélectionnez Ajouter en tant que lien. "
uriel
Cela a très bien fonctionné pour moi. J'essaie de penser à une situation où cela ne fonctionnerait pas ... Et j'y ai suffisamment réfléchi maintenant. Merci!
Dudeman3000
53

Que vous utilisiez Team System Test ou NUnit , la meilleure pratique consiste à créer une bibliothèque de classes distincte pour vos tests. Le simple fait d'ajouter un App.config à votre projet de test sera automatiquement copié dans votre dossier bin lors de la compilation .

Si votre code repose sur des tests de configuration spécifiques, le tout premier test que j'écrirais valide 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 sorte que vos objets de configuration soient passés dans vos classes. Cela vous sépare non seulement du problème du fichier de configuration, mais cela vous permet également 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());
     }
}
bryanbcook
la source
2
Je suis d'accord avec l'esprit de passage dans la dépendance de configuration ici, cela semble avoir été répondu, par Mark Seemann pas moins! ici: Échec des tests unitaires en raison d'un fichier .config manquant
Shaun
Il y a un "absent de la ligne: string value = ConfigurationManager.AppSettings [" TestValue]; J'ai essayé de le réparer, mais j'aurais dû trouver 5 caractères supplémentaires à corriger pour que stackoverflow me permette de faire une modification.
Jane
22

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

Une façon de le résoudre consiste à copier web.config pour tester le projet et à le renommer en app.config.

Une autre et meilleure solution consiste à modifier la chaîne de construction et à en faire une copie automatique de web.config pour tester le répertoire de sortie des projets. Pour ce faire, cliquez avec le bouton droit sur Test Application et sélectionnez les propriétés. Vous devriez maintenant voir les propriétés du projet. Cliquez sur "Build Events", puis 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 devez probablement changer WebApplication1 lorsque vous nom de projet que vous souhaitez tester). Si vous avez un chemin incorrect vers web.config, la copie échoue et vous le remarquerez lors de la construction infructueuse.

Éditer:

Pour copier du projet en cours vers le projet de test:

copy "$(ProjectDir)bin\WebProject.dll.config" "$(SolutionDir)WebProject.Tests\bin\Debug\App.Config"
Antti
la source
Solution vraiment sympa. Cela m'a aidé à éviter de copier et de dupliquer des .configfichiers. Merci d'avoir partagé! :)
Leniel Maccaferri
Très belle solution! Merci beaucoup.
Vin Shahrdar
Belle solution, mais que se passe-t-il lorsque le principal web.confign'a que des références à des .configfichiers externes au sein d'un même projet. Comme le chemin ne peut pointer que vers des dossiers dans le même répertoire (ce qui est normalement vrai), lors de l'exécution de tests, il ne pourra pas gérer ces fichiers externes. Une idée de comment le résoudre?
Sugafree
Cela a fonctionné pour moi: copiez "$ (SolutionDir) \ MainProject \ Web.config" "$ (ProjectDir) app.config"
Andrew
8

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

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

pour les tests unitaires, la configuration ne devrait vraiment pas faire partie de vos tests, alors créez une maquette que vous pouvez injecter. Dans cet exemple, j'utilisais 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");
MichaelChan
la source
5

C'est très simple.

  • Faites un clic droit sur votre projet de test
  • Ajouter -> Élément existant
  • Vous pouvez voir une petite flèche juste à côté du bouton Ajouter
  • Sélectionnez le fichier de configuration cliquez sur "Ajouter en tant que lien"
Hari Das
la source
4

Si vous utilisez NUnit, jetez un œil à cet article . Fondamentalement, vous devrez avoir votre app.config dans le même répertoire que votre fichier .nunit.

Cory Foy
la source
J'utilise VS08 Team System pour mes tests unitaires mais merci pour le conseil NUnit!
Jordan Parmer
2

Si votre application utilise un paramètre tel que Asp.net ConnectionString, vous devez ajouter l'attribut HostType à votre méthode, sinon ils ne se chargeront pas même si vous avez un fichier App.Config.

[TestMethod]
[HostType("ASP.NET")] // will load the ConnectionString from the App.Config file
public void Test() {

}
Zyo
la source
0

J'utilise NUnit et dans mon répertoire de projet j'ai une copie de mon App.Config que je change une configuration (exemple je redirige vers une base de données de test ...). Vous devez l'avoir dans le même répertoire du projet testé et tout ira bien.

Patrick Desjardins
la source
0

Je n'ai pu obtenir aucune de ces suggestions pour fonctionner avec nUnit 2.5.10, j'ai donc fini par utiliser la fonctionnalité Project -> Edit de nUnit pour spécifier le fichier de configuration à cibler (comme d'autres l'ont dit, il doit être dans le même dossier que le. nunit lui-même). Le côté positif de ceci est que je peux donner au fichier de configuration un nom Test.config qui rend beaucoup plus clair ce que c'est et pourquoi)

Jeanne
la source
0

Vos tests unitaires sont considérés comme un environnement qui exécute votre code pour le tester. Tout comme n'importe quel environnement normal, vous avez ie staging / production. Vous devrez peut-être également ajouter un .configfichier pour votre projet de test. Une solution de contournement consiste à créer une bibliothèque de classes et à la convertir en projet de test en ajoutant les packages NuGet nécessaires tels que NUnit et NUnit Adapter. cela fonctionne parfaitement avec Visual Studio Test Runner et Resharper et vous avez votre app.configfichier dans votre projet de test. entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

entrez la description de l'image ici

Et finalement débogué mon test et la valeur de App.config:

entrez la description de l'image ici

Ben
la source