2017-11-07 6 views
1

AutoFixtureには、同じデータを持つ特定の型の複数のインスタンスを作成する機能がありますか?私のクラスはシリアライズ可能ではなく、私は2つのモデルが必要です。すべてのプロパティを持つ複合型の生成

public class Foo 
{ 
    // Many more properties and similar models needing the same semantics. 
    public string Name { get; set; } 
} 

var a = fixture.Create<Foo>(); 
var b = fixture.Create<Foo>(); 

Assert.False(ReferenceEquals(a, b)); 
Assert.Equal(a.Name, b.Name); 

答えて

0

私はAutoFixtureこれを行うことができると思いますが、Albedo缶はありません。これは概念実証コードに過ぎませんが、一般的な考え方を説明する必要があります。

ReflectionVisitor<T>から派生する、新しいクラスを作成します。

public class PropertyCopyVisitor<T> : ReflectionVisitor<T> 
{ 
    private readonly T source; 
    private readonly T destination; 

    public PropertyCopyVisitor(T source, T destination) 
    { 
     this.source = source; 
     this.destination = destination; 
    } 

    public override IReflectionVisitor<T> Visit(
     PropertyInfoElement propertyInfoElement) 
    { 
     var pi = propertyInfoElement.PropertyInfo; 
     pi.SetValue(this.destination, pi.GetValue(this.source)); 
     return this; 
    } 

    public override T Value 
    { 
     get { return this.destination; } 
    } 
} 

を実装の極めて重要な部分は、それがsourcedestinationへのオブジェクトから各プロパティをコピーするためにリフレクションを使用していますVisit過負荷です。あなたは今、あなたのテストを書くことができ

この実装はValueプロパティが使用されることはありません、destination変異するが、それはそれはReflectionVisitor<T>abstractだからそこに持っているので

...など:

var fixture = new Fixture(); 
var a = fixture.Create<Foo>(); 
var b = fixture.Create<Foo>(); // Or just create a new, empty Foo... 
// This copies all properties from a to b: 
new TypeElement(typeof(Foo)).Accept(new PropertyCopyVisitor<Foo>(a, b)); 

Assert.False(ReferenceEquals(a, b)); 
Assert.Equal(a.Name, b.Name); 

ここではfixtureを使用してbを作成しましたが、すべてのプロパティが上書きされるため、これを行う必要はありません。 Fooにパラメータのないコンストラクタがある場合は、単にnew Foo()を使用できます。それは何の違いもありません。

この概念実証は、明示的にプロパティをコピーするだけです。フィールドをコピーする必要がある場合は、適切なVisitメソッドもオーバーライドする必要があります。さらに、問題のオブジェクトがコンストラクタ引数を取る場合は、明示的にそれらに対処する必要があります。

new TypeElement(typeof(Foo)).Accept(new PropertyCopyVisitor<Foo>(a, b));と書くのが面倒だと思ったら、その周りにヘルパーメソッドを書く方法を考え出すことができます。追加の注意点としては

PropertyCopyVisitorは、それが実際に何のためのT型引数を使用しないため、汎用的であることをを持っていません。私はこれがコンストラクタを与える型の安全性が好きです...

関連する問題