172 Stimmen

Kann ein Unit-Test-Projekt die app.config-Datei der Zielanwendung laden?

Ich teste eine .NET-Anwendung (.exe), die eine app.config-Datei zum Laden von Konfigurationseigenschaften verwendet. Die Unit-Test-Anwendung selbst verfügt nicht über eine app.config-Datei.

Wenn ich versuche, eine Methode zu testen, die eine der Konfigurationseigenschaften verwendet, geben sie null . Ich nehme an, dass dies daran liegt, dass die Unit-Test-Anwendung nicht in die app.config der Zielanwendung geladen wird.

Gibt es eine Möglichkeit, dies zu überschreiben oder muss ich ein Skript schreiben, um den Inhalt der Ziel app.config in eine lokale app.config zu kopieren?

Diese Beitrag stellt diese Frage, aber der Autor betrachtet sie aus einem anderen Blickwinkel als ich.

EDIT: Ich sollte erwähnen, dass ich VS08 Team System für meine Unit-Tests verwende.

131voto

In Visual Studio 2008 habe ich die app.config Datei als bestehendes Element in das Testprojekt und wählte als Verknüpfung kopieren, um sicherzustellen, dass sie nicht dupliziert wird. Auf diese Weise habe ich nur eine Kopie in meiner Lösung. Bei mehreren Testprojekten ist das wirklich praktisch!

Add Existing Item

Add As Link

8 Stimmen

Perfekte Antwort, einfach und objektiv! +1

3 Stimmen

Dies ist die beste Lösung und sollte als Antwort markiert werden.

5 Stimmen

Um ein bestehendes Element "als Link" hinzuzufügen, sollten Sie: "Suchen Sie im Dialogfeld Vorhandenes Element hinzufügen das Projektelement, das Sie verknüpfen möchten, und wählen Sie es aus", und dann: "Wählen Sie aus der Dropdown-Liste der Schaltfläche Öffnen die Option Als Verknüpfung hinzufügen."

64voto

Jeromy Irvine Punkte 11205

Der einfachste Weg, dies zu tun, ist das Hinzufügen der .config Datei im Deployment-Abschnitt Ihres Unit-Tests.

Dazu öffnen Sie die .testrunconfig Datei aus Ihren Solution Items. Fügen Sie im Abschnitt "Deployment" die Ausgabe .config Dateien aus dem Build-Verzeichnis Ihres Projekts (vermutlich bin\Debug ).

Alles, was im Abschnitt "Deployment" aufgeführt ist, wird in den Arbeitsordner des Testprojekts kopiert, bevor die Tests ausgeführt werden, so dass Ihr konfigurationsabhängiger Code problemlos ausgeführt werden kann.

Bearbeiten: Ich habe vergessen, hinzuzufügen, dass dies nicht in allen Situationen funktioniert, so dass Sie möglicherweise ein Startskript einfügen müssen, das die Ausgabe umbenennt .config mit dem Namen des Einheitstests übereinstimmen.

9 Stimmen

Es ist viel einfacher, dem Testprojekt einfach ein app.config-Feld hinzuzufügen - dann müssen Sie nicht mehr mit der .testrunconfig herumspielen.

13 Stimmen

@Rowland Wenn Sie das tun, müssen Sie zwei Kopien von app.config pflegen. Ich verbringe lieber einmal 10 Sekunden damit, das Tool .testrunconfig zu verwenden, als mich daran zu erinnern, die app.config an beiden Orten zu aktualisieren.

72 Stimmen

Können Sie nicht einfach einen nicht kopierenden Verweis hinzufügen? (Vorhandenes Element hinzufügen...)

57voto

bryanbcook Punkte 15032

Ob Sie nun Team System Test o NUnit Am besten erstellen Sie eine eigene Klassenbibliothek für Ihre Tests. Wenn Sie eine App.config zu Ihrem Testprojekt hinzufügen, wird sie beim Kompilieren automatisch in Ihren bin-Ordner kopiert .

Wenn Ihr Code auf bestimmte Konfigurationstests angewiesen ist, würde ich als allererstes einen Test schreiben, der überprüft, ob die Konfigurationsdatei verfügbar ist ( damit ich weiß, dass ich nicht geisteskrank bin ) :

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

Und der Test:

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

Idealerweise sollten Sie Ihren Code so schreiben, dass Ihre Konfigurationsobjekte an Ihre Klassen übergeben werden. Dies trennt Sie nicht nur vom Problem der Konfigurationsdatei, sondern ermöglicht es Ihnen auch, Tests für verschiedene Konfigurationsszenarien zu schreiben.

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 Stimmen

Ich stimme mit dem Geist des Übergangs in die Konfigurationsabhängigkeit hier überein, dies scheint beantwortet worden zu sein, von Mark Seemann nicht weniger! hier: Fehlgeschlagene Unit-Tests aufgrund einer fehlenden .config-Datei

0 Stimmen

Es fehlt ein " in der Zeile: string value = ConfigurationManager.AppSettings["TestValue]; Ich habe versucht, es zu korrigieren, aber ich hätte weitere 5 Zeichen finden müssen, um es zu korrigieren, damit Stackoverflow mir erlaubt, eine Bearbeitung vorzunehmen.

25voto

Antti Punkte 903

Wenn Sie eine Lösung haben, die z. B. eine Webanwendung und ein Testprojekt enthält, möchten Sie wahrscheinlich, dass das Testprojekt die web.config der Webanwendung verwendet.

Eine Möglichkeit, dieses Problem zu lösen, besteht darin, die Datei web.config in das Testprojekt zu kopieren und sie in app.config umzubenennen.

Eine andere und bessere Lösung besteht darin, die Build-Kette so zu ändern, dass sie automatisch eine Kopie der web.config in das Ausgabeverzeichnis des Testprojekts erstellt. Klicken Sie dazu mit der rechten Maustaste auf Testanwendung und wählen Sie Eigenschaften. Nun sollten Sie die Projekteigenschaften sehen. Klicken Sie auf "Build Events" und dann auf die Schaltfläche "Edit Post-build...". Schreiben Sie die folgende Zeile dort hinein:

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

Und klicken Sie auf OK. (Beachten Sie, dass Sie höchstwahrscheinlich WebApplication1 als Projektnamen ändern müssen, den Sie testen möchten). Wenn Sie den falschen Pfad zu web.config haben, schlägt das Kopieren fehl und Sie werden es während des fehlgeschlagenen Builds bemerken.

Edit :

So kopieren Sie aus dem aktuellen Projekt in das Testprojekt:

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

0 Stimmen

Eine wirklich gute Lösung. So konnte ich das Kopieren und Duplizieren vermeiden. .config Dateien. Danke fürs Teilen! :)

0 Stimmen

Sehr gute Lösung! Herzlichen Dank!

0 Stimmen

Nette Lösung, aber was passiert, wenn die Haupt web.config haben nur Verweise auf externe .config Dateien innerhalb desselben Projekts. Da der Pfad nur auf Ordner innerhalb desselben Verzeichnisses verweisen kann (was normalerweise der Fall ist), kann er bei der Ausführung von Tests diese externen Dateien nicht verarbeiten. Haben Sie eine Idee, wie man das Problem lösen kann?

10voto

MichaelChan Punkte 1728

Das ist zwar schon etwas älter, aber ich habe eine bessere Lösung für dieses Problem gefunden. Ich habe die hier gewählte Antwort versucht, aber es sieht so aus, als ob .testrunconfig bereits veraltet ist.

1. Für Unit-Tests, Wrap the config ist ein Interface (IConfig)

für Unit-Tests, sollte die Konfiguration wirklich nicht Teil dessen sein, was Sie testen, also erstellen Sie ein Mock, das Sie injizieren können. In diesem Beispiel habe ich Moq verwendet.

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

2. Für den Integrationstest fügen Sie die benötigte Konfiguration dynamisch hinzu

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X