マニュアル フェイクに渡す必要のあるパラメーターの種類によっては、AutoFixture の組み込みのInlineAutoDataAttribute
.
これらを考えると
public interface IHardToMockDependency
{
string Value { get; }
}
public class FakeHardToMockDependency : IHardToMockDependency
{
private readonly string _value;
public FakeHardToMockDependency(string value)
{
_value = value;
}
#region IHardToMockDependency Members
public string Value
{
get { return this._value; }
}
#endregion IHardToMockDependency Members
}
インターフェイスICustomization
の実装を作成する方法をフィクスチャ オブジェクトに伝える実装を作成します。IHardToFakeDependency
public class FakeHardToMockDependencyCustomization : ICustomization
{
private readonly string _value;
public FakeHardToMockDependencyCustomization(string value)
{
_value = value;
}
#region ICustomization Members
public void Customize(IFixture fixture)
{
fixture.Register<IHardToMockDependency>(() => new FakeHardToMockDependency(this._value));
}
#endregion ICustomization Members
}
もちろん、これは渡したい文字列を知る必要があることに注意してください。
次に、これを で使用する他のカスタマイズと合わせてロールアップしますCompositeCustomization
。
public class ManualFakeTestConventions : CompositeCustomization
{
public ManualFakeTestConventions(string value)
: base(new FakeHardToMockDependencyCustomization(value), new AutoMoqCustomization())
{
}
}
ここで Mark Seemannが説明しているように、カスタマイズは常に最も具体的なものから最も一般的なものの順に配置してください。
AutoDataAttribute
次に、このカスタマイズを使用する実装を作成します。
public class ManualFakeAutoDataAttribute : AutoDataAttribute
{
public ManualFakeAutoDataAttribute(string value)
: base(new Fixture().Customize(new ManualFakeTestConventions(value)))
{
}
}
これは、 と同じように使用できるようになりましたInlineAutoDataAttribute
:
public class ManualFakeTests
{
[Theory, ManualFakeAutoData("iksdee")]
public void ManualFake(IHardToMockDependency fake)
{
Assert.IsType<FakeHardToMockDependency>(fake);
Assert.Equal("iksdee", fake.Value);
}
}
[Frozen]
Theory パラメータに属性を適用することで、自動作成された SUT インスタンスにすぐに挿入することもできます。
[Theory, ManualFakeAutoData("iksdee")]
public void SutWithManualFake([Frozen] IHardToMockDependency fake, MySut sut)
{
}
これにより、MySut
インスタンスとIHardToMockDependency
コンストラクターに必要なインスタンスが作成されます。これには、 AutoFixture で規則を指定し、そのインスタンスそのものを変数FakeHardToMockDependencyCustomization
として提供しfake
ます。
偽物を凍結しなくても正しいFakeHardToMockDependency
インスタンスが得られ、sut に挿入されますが、カスタマイズでファクトリ デリゲートを登録しているため、それらは異なることに注意してください。インスタンスをフリーズすると、フィクスチャはインターフェイスに対する後続のリクエストに対して常に同じインスタンスを返すようになります。
ただし、これにはいくつかの注意事項があります。
- パラメータとして渡す文字列への参照がないため、文字列リテラルとして 2 回指定する必要があります。たとえば、テストクラス内の文字列定数を使用してこれを回避できます。
- .NET で属性パラメーターとして使用できる型の数は限られています。基本的な型さえあればいいのですが、パラメータリストでコンストラクタなどを呼び出すことはできません。
- この属性は、インスタンスが必要な場合にのみ使用してください
IHardToFakeDependency
。それ以外の場合は、常に文字列パラメーターを渡す必要があります。使用する必要がある一連の標準カスタマイズがある場合は、それらのみを含む別の属性を作成します。
- の機能が
InlineAutoDataAttribute
同時に必要な場合は、両方の機能を組み合わせた別の属性も作成する必要があります。
具体的な状況によっては、xUnit.net の も見たいと思うかもしれませんがPropertyDataAttribute
、それを使用していることはほとんどありません。
一般に、私の意見では、カスタマイズと autodata 属性を操作する方法と、独自の属性をいつどのように作成するかを理解することが、AutoFixture を効果的に使用し、実際に作業を節約するための鍵です。
テストが必要な特定のドメインでコードを頻繁に作成する場合は、xUnit.net、AutoFixture の隣にドロップすればいつでもすぐに使用できる、カスタマイズ、属性、およびスタブ オブジェクトを含むライブラリを作成するのが理にかなっています。とモク。私は私が私のものを作ってとてもうれしいことを知っています。
ああ、また: モックするのが難しい依存関係を持つことは、設計上の問題を示している可能性があります。嘲笑するのがなぜそんなに難しいのですか?