2013-06-08 5 views
8

Mit AutoFixture als SutFactory kann ich feststellen, dass dieser Wert dann verwendet wird, wenn ich einen Wert für einen Typ registriere oder einfriere für alle nachfolgenden Verwendungen dieses Typs. Aber wenn ich eine Klasse mit zwei Parametern, die die gleiche Art an den Konstruktor sind wie:Definieren/Verwalten> 1 Konstruktorparameter desselben Typs mit unabhängigen Werten bei Verwendung von AutoFixture als SutFactory

public class ClassA 
{ 
    public double ParameterA { get; private set;} 
    public double ParameterB { get; private set;} 

    public ClassA(double parameterA, double parameterB) 
    { 
     ParameterA = parameterA; 
     ParameterB = parameterB; 
    } 

    public void Execute(ClassB object) 
    { 
     object.Value = (object.Value * ParameterA) /ParameterB; 
    } 
} 

Welche Strategien gibt es für autofixture unter Verwendung der einzigartigen vordefinierten Werten für ParameterA und parameterB im Hinblick auf die Prüfung zu injizieren der berechnete Wert?

* Leider kann ich mein genaues Szenario hier nicht teilen, aber es verwendet das Befehlsmuster, um auf einem anderen Objekt zu arbeiten, so die einzige Möglichkeit, ParameterA und ParameterB bei der Pflege des Designs zu setzen, ist sie in und den Konstruktor zu injizieren ist der beste Weg, dies in diesem Fall zu tun.

+0

http://stackoverflow.com/a/15550506/11635 löst das Problem, aber @Mark Seemanns Antwort ist wahrscheinlich eine bessere Straße –

Antwort

2

mit den Merkmalen ein bisschen mehr verwendet wird, ich persönlich festgestellt, dass es nicht zu viele Objekte ist, wo dies geschieht, so eine einfache Anpassung für die Klasse zu schaffen ist wahrscheinlich am besten hier, zum Beispiel:

public class ClassACustomization: ICustomization 
{ 
    public double ParameterA { get; set;} 
    public double ParameterB { get; set;} 

    public void Customize(IFixture fixture) 
    { 
     //Note: these can be initialized how you like, shown here simply for convenience. 
     ParameterA = fixture.Create<double>(); 
     ParameterB = fixture.Create<double>(); 
     fixture.Customize<ClassA>(c => c 
      .FromFactory(() => 
      new ClassA(ParameterA , ParameterB))); 
    } 
} 

I finde, dass dies mir immer noch die Flexibilität gibt, die bei AutoFixture groß ist, ohne die Möglichkeit zu beeinträchtigen, in bestimmten Instanzen von ParameterA oder ParameterB zu injizieren (Sie könnten sie mit Builder-Methoden, Konstruktor usw. einrichten) Werte).

5

Eine Option ist die Anpassung des Erstellungsalgorithmus für alle Instanzen von ClassA.

var valueA = 1; 
var valueB = 2; 

var fixture = new Fixture(); 
fixture.Customize<ClassA>(c => c 
    .FromFactory(() => 
     new ClassA(valueA, valueB))); 

var result = fixture.Create<ClassA>(); 
// -> parameterA value is 1 
// -> parameterB value is 2 
+2

Nur neugierig ... Jeder Grund, den Sie wählen, markieren Sie "Anpassen" statt "Register" ? –

+0

Nein, kein besonderer Grund .. Eigentlich ist 'Customize' expliziter. Sowohl' Register' als auch 'Customize' ergeben das gleiche Ergebnis :) –

+0

@RubenBartelink, es ist mein Verständnis, dass das Register dieses Szenario nicht lösen würde würde einfach beide Argumente auf den gleichen Wert setzen. Im obigen Fall muss ich wirklich zwei verschiedene Parameter angeben, die ich steuern kann, um injiziert zu werden. Vorzugsweise halte ich meine Tests für zukünftige Konstruktorargumente flexibel. – gmn

5

Es ist meine Beobachtung, dass die meisten der Zeit, als ich ein Szenario wie das begegnen, brauche ich nicht besonders zu Kontrolle die Werte, bevor sie an den Konstruktor übergeben sind, sondern vielmehr, dass ich brauche, um wissen was die Werte sind.

, das einfach durch erreichen Structural Inspection Properties der Klasse hinzufügen:

public class ClassA 
{ 
    public ClassA(double parameterA, double parameterB) 
    { 
     this.A = parameterA; 
     this.B = parameterB; 
    } 

    public double A { get; private set } 

    public double B { get; private set } 
} 

Jetzt können Sie AutoFixture fragen eine Instanz von Klasse A ohne weiteres zu schaffen und anschließend die Instanz über die Werte abfragen.

+0

Normalerweise stimme ich Ihnen zu. In diesem Fall (was ich in der Frage nicht klargestellt habe) denke ich eher an eine Situation, in der ich eine Berechnung habe, die von den beiden Werten abhängt, die ich überprüfen möchte. Ich muss wirklich wissen, was die beiden Argumente sind, um eine vernünftige Eingabe für die Berechnung zu haben, die ich verifizieren kann. – gmn

+3

Wenn Sie für einen Moment den Fall betrachten, in dem die Abhängigkeiten keine Primitiven, sondern Schnittstellen sind, sollte der genaue Wert keine Rolle spielen. Wenn dies der Fall ist, bricht die Klasse wahrscheinlich das Liskow-Substitutionsprinzip. Aus der Erfahrung heraus fange ich an zu denken, dass das gleiche Prinzip für primitive Abhängigkeiten gilt. Wenn der Wert zählt, ist es wahrscheinlich keine Abhängigkeit. Vielleicht werden diese Werte besser als Methodenargumente übergeben? Oder stellt sich heraus, dass sie besser als Interfaces oder Klassen modelliert werden? Können Sie Ihr Szenario teilen? –

+0

Ich sehe, Sie sind Punkt, und stimmen im Allgemeinen überein, ich habe aktualisiert, um ein bisschen genauer oben zu sein, wenn das hilft, etwas Licht auf das, was ich versuche zu erreichen. – gmn