9

ich eine Klassenbibliothek habe ich zu Unit-Test-Framework Microsofts Gerät zu testen will. Einige der Klassen, die ich testen möchte, werden mithilfe von Anwendungseinstellungen konfiguriert. Diese Einstellungen sind in der Datei Settings.settings definiert, die einen Anwendungsumfang und geeignete Standardwerte hat. Wenn die Bibliothek von der Anwendung verwendet wird, können diese Einstellungen in der Datei App.Config überschrieben werden. Wenn nicht, werden die Standardwerte verwendet. Genau so will ich es haben.Ändern der Anwendungseinstellungen in Unit-Tests

In einige meiner Testfällen mag ich spezielle Kombinationen von Werten testen Einstellung, aber ich weiß nicht, wie die Werte von der Klasse unter Test aus dem Unit-Test-Code gesehen zu ändern. Für diese Einstellungen wird immer der Standardwert aus den Attributen der vom Code generierten Klasse geladen.

In meiner Bibliothek Klasse greife ich auf die Einstellungen wie folgt aus:

var mySetting1 = Settings.Default.MySetting1; 
var mySetting2 = Settings.Default.MySetting2; 

Wie kann ich diese Einstellungen in einem Unit-Test ändern, bevor die Einstellung von der Klasse unter Test zugegriffen wird? Durch den Zugriff auf die interne Einstellungsklasse durch den Komponententest wird das Problem nicht gelöst, da die Einstellungen einen Anwendungsumfang haben und schreibgeschützte Eigenschaften für die Einstellungsklasse sind.

Antwort

14

Nach Spelunking in die ApplicationSettingsBase und zugehörigen Klassen Ich habe mit dieser Lösung zu meinem Problem kommen. Nicht besonders schön, aber es wird sicherlich die Arbeit erledigt.

Der Code erzeugt Einstellungen Klasse ist der Klassenbibliothek Projekt interne und es muss das Gerät Testprojekt zugänglich sein. Fügen Sie das [assembly: InternalsVisibleTo("UnitTestAssemblyName")]-Attribut zu AssemblyInfo.cs in dem Klassenbibliotheksprojekt hinzu.

Die Einstellungen sind lazy aus den Attributen auf der Einstellungs Klasse geladen, wenn ein Wert zugegriffen wird. Der erste Schritt besteht darin, eine "Dummy" -Lesung einer Einstellung auszuführen, um diese verzögerte Belastung zu erzwingen. Wenn Sie beim Komponententest versuchen, Einstellungswerte zu vermeiden, die in einem Test geändert wurden, um einen anderen zu beeinflussen, müssen Sie die Einstellungen vor dem verzögerten Laden "zurücksetzen". Dies kann mit der Methode Reload() erfolgen. Dieser Code wird in der Test Methode initialize gelegt:

Settings.Default.Reload(); 
var dummy = Settings.Default.MySetting1; 

Die zugrunde liegenden Werte existieren jetzt und in jedem Testverfahren festgelegt werden. Denken Sie daran, die richtige Art wie die Code generiert Getter zu verwenden, wird eine Besetzung tun:

Settings.Default.PropertyValues["MyStringSetting1"].PropertyValue = "Foobar"; 
Settings.Default.PropertyValues["MyDoubleSetting2"].PropertyValue = 3.1416D; 
+0

+1 für die Problemumgehung Reload + Eigenschaft Accessor. –

+0

Danke dafür, hätte es nie alleine herausgefunden. –

5

würde ich eine Wrapper-Klasse um die Settings Klasse erstellen dann um diese Wrapper übergeben. Dann können Sie Ihren Einstellungs-Kurs mit Leichtigkeit üben.

Die einzige andere Sache, die ich mit oben kommen kann, ist das etwas leichter und einfacher zu mock-Option machen Sie Ihre Einstellungen ein Interface-Datei implementieren, die alle Einstellungen widerspiegelt. Es ist nicht viel anders für den Anrufer, aber Sie müssen weniger Klempner tun, wenn Sie neue Einstellungen hinzufügen.

Weder ist fantastisch, und es ist ein Schmerz, es für automatisch generierten Code zu tun, aber es scheint, dass das, was wir stecken, soweit ich sagen kann, wenn Sie wirklich die Abhängigkeit von der entfernen möchten Einstellungsdatei.

z. für eine Einstellungsdatei einer Zeichenfolge Anwendungseinstellung und eine int Benutzereinstellung enthält:

internal sealed partial class Settings : IMySettings { 

    /* 
    * here be auto-generate code (and dragons!) 
    */ 
} 

internal interface IMySettings 
{ 
    string ApplicationSetting 
    { 
     get; 
    } 

    string UserSetting 
    { 
     get; 
     set; 
    } 
} 
+0

würde ich lieber vermeiden Einstellungen injizieren, da ich viele Bibliotheken und die Anzahl der Abhängigkeiten zu injizieren wächst viel wie ich die Abhängigkeitshierarchie nach oben .Darüber hinaus ist das Umbrechen von Klassen, die von Visual Studio generiert werden, mühsam. Ich habe auf eine Lösung gehofft, die nicht reine DI war, aber gut mit den Anwendungseinstellungen in .NET funktionieren würde. –

+0

Leider glaube ich nicht, dass es einen gibt, das Beste, was Sie tun können, ist die Benutzereinstellung, aber die Anwendungseinstellungen ändern sich nicht außerhalb der Datei. Die einzige andere Sache, die ich mir im Moment vorstellen kann, ist die Verwendung eines Interface, etwas leichter, aber trotzdem, wie du sagst, reines DI. –

Verwandte Themen