2015-01-07 5 views
16

Ist es möglich, einer Eigenschaft in einer untergeordneten Instanz einen festen Wert zuzuweisen, wenn ein übergeordnetes Element mit Autofixtion erstellt wird? Es fügt allen Eigenschaften der untergeordneten Instanz Standardwerte wie einen Charm hinzu, möchte jedoch einen bestimmten Wert für eine der Eigenschaften der untergeordneten Instanz überschreiben und zuweisen.Festlegen des Eigenschaftswerts für untergeordnete Instanz auf einen festen Wert mit AutoFixtion

diese Eltern/Kind-Beziehung:

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public Address Address { get; set; } 
} 

public class Address 
{ 
    public string Street { get; set; } 
    public int Number { get; set; } 
    public string City { get; set; } 
    public string PostalCode { get; set; } 
} 

Ich möchte einen bestimmten Wert an die Stadt Eigenschaft auf der Adresse Instanz zuzuweisen. Ich dachte in den Zeilen dieses Testcodes:

var fixture = new Fixture(); 

var expectedCity = "foo"; 

var person = fixture 
    .Build<Person>() 
    .With(x => x.Address.City, expectedCity) 
    .Create(); 

Assert.AreEqual(expectedCity, person.Address.City); 

Das ist nicht möglich. Ich denke, durch die Reflexion Ausnahme

System.Reflection.TargetException : Object does not match target type. 

... dass Autofixture versucht, den Wert in eine Stadt Eigenschaft auf der Person Instanz anstelle einer Adresse Instanz zuzuweisen.

Irgendwelche Vorschläge?

Und ja, ich weiß, dass ich nur ein zusätzlicher Schritt wie folgt hinzufügen könnte:

var fixture = new Fixture(); 

var expectedCity = "foo"; 

// extra step begin 
var address = fixture 
    .Build<Address>() 
    .With(x => x.City, expectedCity) 
    .Create(); 
// extra step end 

var person = fixture 
    .Build<Person>() 
    .With(x => x.Address, address) 
    .Create(); 

Assert.AreEqual(expectedCity, person.Address.City); 

... aber hatte gehofft, für die erste Version oder etwas ähnliches (weniger Schritte, mehr terse).

Hinweis: Ich verwende Autofixture v3.22.0

+0

bezogen werden: http://stackoverflow.com/a/11657881/11635 –

Antwort

5

Nicht zu abweisend auf die Frage, aber die einfachste Lösung könnte tatsächlich dies sein:

Die Zuweisung von expliziten Werten zu Eigenschaften ist etwas, was die meisten Sprachen bereits auszeichnen (C# sicherlich), also glaube ich nicht, dass AutoFixture eine komplizierte DSL benötigt, um die Hälfte dieser Funktionalität zu reproduzieren.

+0

Während es für die meisten von uns offensichtlich ist, dass die Zuweisung von expliziten Werten zu Eigenschaften in C# (fast) ohne Aufwand ist ursprüngliche Frage war, kann ich in einer Eltern/Kind-Beziehung einen festen Wert einer Eigenschaft des Kindes _with_ Autoftixture zuweisen. Der Grund für die Frage ist nur auf die Ästhetik, da ich denke, dass die Gruppierung der Wertzuweisungen mit .With (....) -Syntax bei mehrfachen Zuweisungen (so subjektiv wie dies ist) "hübscher" wäre. Ästhetik beiseite, Ihre Antwort macht den Job erledigt. –

+0

Sie können einen Wert korrigieren, indem Sie einen benutzerdefinierten 'ISpecimenBuilder' implementieren, aber nicht (denke ich) mit dem fließenden DSL, wenn es sich um eine Zugwrack-Eigenschaft handelt. Ich habe den Eindruck von der Frage bekommen, die Sie angestrebt haben, aber wenn Sie den konventionsbasierten Ansatz bevorzugen, werde ich ihn gerne teilen. –

+0

Nein, aber trotzdem danke. Das Zugunglück ist an der äußersten Grenze meiner Anwendung geparkt und modelliert einfach eine eingehende Datenstruktur, also werde ich mit einer Handvoll Testfällen leben, die ... naja ... weniger hübsch aussehen ;-) –

-1

Sie ein Methode auf dem Builder Sie verwenden können:

var person = this.fixture 
       .Build<Person>() 
       .Do(x => x.Address.City = expectedCity) 
       .Create(); 

Sie können auch Ihre Instanz an der Befestigung injizieren und einfrieren:

+0

Waren Sie schon in r tatsächlich versucht un diesen Code? Es löst eine NullReferenceException aus, wenn ich es ausführe. –

+0

...und Inject setzt alle Zeichenfolgeneigenschaften auf den Wert von expectedCity - nicht wirklich, was ich will –

+0

Tatsächlich gibt es eine NullReferenceException für die * Do * -Methode, was IMO als Fehler angesehen werden kann, weil diese Methode von der Schnittstelle * IPostprocessComposer kommt *, also sollte die Nachbearbeitung erfolgen, nachdem das Objekt und seine Abhängigkeiten erstellt wurden. – sgnsajgon

9

Der Vollständigkeit halber ist hier eine andere Art und Weise, es zu tun:

fixture.Customize<Address>(c => 
    c.With(addr => addr.City, "foo")); 

var person = fixture.Create<Person>(); 

Dies wird die Erstellung aller Instanzen von Address

anpassen Wenn Sie dies oft genug am Ende mit, kann es es Einwickeln lohnen innen ein ICustomization:

public class AddressConventions : ICustomization 
{ 
    public void Customize(IFixture fixture) 
    { 
     fixture.Customize<Address>(c => 
      c.With(addr => addr.City, "foo")); 
    } 
} 

fixture.Customize(new AddressConventions()); 
Verwandte Themen