私は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; }
}
}
を実装の極めて重要な部分は、それがsource
destination
へのオブジェクトから各プロパティをコピーするためにリフレクションを使用しています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
型引数を使用しないため、汎用的であることをを持っていません。私はこれがコンストラクタを与える型の安全性が好きです...