これについて移動する様々な方法があります。ここで
命令型バージョン
はOPで提供1よりも簡単不可欠バージョンです:the default number of many items is 3ながら
[Fact]
public void ImperativeTest()
{
var fixture = new Fixture();
var expected = fixture.CreateMany<SyncItem>(3).OrderBy(si => si.Key);
var unorderedItems = expected.Skip(1).Concat(expected.Take(1)).ToArray();
fixture.Inject(unorderedItems);
var sut = fixture.Create<SyncItemList>();
Assert.Equal(expected, sut);
}
、私はそれがこのテストケースで明示的にそれを呼び出すために、より良いだと思います。ここで使用されるスクランブリングアルゴリズムは、後は順不同リストにバックマスト結果を最初の要素を移動する、3(別個の)要素のシーケンスを順序付けするという事実を利用します。
しかし、このアプローチの問題点は、fixture
の変更に依存しているため、より宣言的なアプローチにリファクタリングすることが難しいことです。(
public class UnorderedSyncItems : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new UnorderedSyncItemsGenerator());
}
private class UnorderedSyncItemsGenerator : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
var t = request as Type;
if (t == null ||
t != typeof(SyncItem[]))
return new NoSpecimen(request);
var items = ((IEnumerable)context
.Resolve(new FiniteSequenceRequest(typeof(SyncItem), 3)))
.Cast<SyncItem>();
return items.Skip(1).Concat(items.Take(1)).ToArray();
}
}
}
new FiniteSequenceRequest(typeof(SyncItem), 3))
は単に弱い型付けされている解決:より宣言バージョンにリファクタリングするための努力において
カスタマイズされたバージョン
は、あなたが最初a Customizationでのスクランブルアルゴリズムをカプセル化することができます非一般的な)SyncItem
インスタンスの有限シーケンスを作成する方法;それはCreateMany<SyncItem>(3)
の背後にあるのです。
これはあなたがテストをリファクタリングすることができます:
[Fact]
public void ImperativeTestWithCustomization()
{
var fixture = new Fixture().Customize(new UnorderedSyncItems());
var expected = fixture.Freeze<SyncItem[]>().OrderBy(si => si.Key);
var sut = fixture.Create<SyncItemList>();
Assert.Equal(expected, sut);
}
はFreeze方法の使用を注意してください。 UnorderedSyncItems
カスタマイズでは、SyncItem[]
のインスタンスが作成される方法のみが変更されるため、これは必要です。これを行う要求を受け取るたびに新しい配列が作成されます。 Freeze
は、fixture
がsut
インスタンスを作成するときにも常に同じ配列が再利用されることを保証します。
条約ベースのテスト
上記試験は[UnorderedConventions]
属性を導入することによって、宣言、規則ベースのテストにリファクタリングすることができる。
public class UnorderedConventionsAttribute : AutoDataAttribute
{
public UnorderedConventionsAttribute()
: base(new Fixture().Customize(new UnorderedSyncItems()))
{
}
}
これは単に宣言型接着剤でありますUnorderedSyncItems
カスタマイズを適用します。テストは現在次のようになります。
[Theory, UnorderedConventions]
public void ConventionBasedTest(
[Frozen]SyncItem[] unorderedItems,
SyncItemList sut)
{
var expected = unorderedItems.OrderBy(si => si.Key);
Assert.Equal(expected, sut);
}
は[UnorderedSyncItems]
と[Frozen]
属性の使用を注意してください。
このテストは非常に簡潔ですが、後になっているテストではない可能性があります。問題は、振る舞いの変化が[UnorderedSyncItems]
属性で隠されていることで、何が起こっているのかは暗黙のことです。私は、全体のテストスイートのための規則のセットとして同じカスタマイズを使用することを好むので、私はこのレベルでテストケースのバリエーションを導入するために好きではありません。ただし、SyncItem[]
のインスタンスがの場合は常ににする必要があると表記している場合、この規則は良好です。
だけ一部のテストケースのための順不同の配列を使用したい場合は、[AutoData]
属性の使用が最も最適な方法ではありません。
宣言テストケース
あなたは、単にちょうど[Frozen]
属性と同様に、パラメータレベルの属性を適用することができればそれは素晴らしいことだろう - おそらく[Unordered][Frozen]
のように、それらを組み合わせます。しかし、このアプローチはうまくいきません。
の注文がであることに注意してください。フリーズする前にUnorderedSyncItems
を適用する必要があります。そうしないと、フリーズするアレイの順序が保証されない場合があります。
[Unordered][Frozen]
パラメータレベルの属性の問題は、コンパイル時に、AutoFixture xUnit.netグルーライブラリが属性を読み取り適用するときに.NET Frameworkが属性の順序を保証しないことです。
代わりに、あなたはこのように、適用する単一の属性を定義することができます。
public class UnorderedFrozenAttribute : CustomizeAttribute
{
public override ICustomization GetCustomization(ParameterInfo parameter)
{
return new CompositeCustomization(
new UnorderedSyncItems(),
new FreezingCustomization(parameter.ParameterType));
}
}
(FreezingCustomization
が[Frozen]
属性の基礎となる実装を提供します。)
これは、あなたがこのテストを書くことができます:
[Theory, AutoData]
public void DeclarativeTest(
[UnorderedFrozen]SyncItem[] unorderedItems,
SyncItemList sut)
{
var expected = unorderedItems.OrderBy(si => si.Key);
Assert.Equal(expected, sut);
}
この宣言テストでは、デフォルトの[AutoData]
属性をCustomiなしで使用していますこれはスクランブリングがパラメータレベルで[UnorderedFrozen]
属性によって適用されるためです。
これは、[AutoData]
-derived属性でカプセル化された(他の)テストスイート全体の規約を使用して、オプトインメカニズムとして[UnorderedFrozen]
を使用することも可能にします。
「SyncItemList」はどのように見えますか? –
属性とUnOrderedリクエストタイプ、有限シーケンスのようなものがあれば、本当にクールだと思います。 3つ以上のユニークなアイテムが必要なだけで、順序が乱れることがあります。 – cocogorilla
どのバージョンのAutoFixtureを使用しているのですか? AutoFixture 3の[数値はランダムです](https://github.com/AutoFixture/AutoFixture/wiki/AutoFixture-3.0-Release-Notes#numbers-are-random) –