AutOfixtureを使用したHTMLヘルパーの単体テスト
-
27-10-2019 - |
質問
AutOfixtureを使用してHTMLヘルパーをユニットテストしようとしています。以下は私のsutです
public static MvcHtmlString SampleTable(this HtmlHelper helper,
SampleModel model, IDictionary<string, object> htmlAttributes)
{
if (helper == null)
{
throw new ArgumentNullException("helper");
}
if (model == null)
{
throw new ArgumentNullException("model");
}
TagBuilder tagBuilder = new TagBuilder("table");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.GenerateId(helper.ViewContext.HttpContext.Items[Keys.SomeKey].ToString());
return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
}
ご覧のとおり、テーブルタグとIDが取り付けられたMVC HTML文字列を返すだけです。 (例については、以下のユニットテスト結果を参照)
Autofixtureを使用した単位テスト:
[Fact]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
{
var fixture = new Fixture();
//Arrange
fixture.Inject<HttpContextBase>(new FakeHttpContext());
var httpContext = fixture.CreateAnonymous<HttpContextBase>();
fixture.Inject<ViewContext>(new ViewContext());
var vc = fixture.CreateAnonymous<ViewContext>();
vc.HttpContext = httpContext;
vc.HttpContext.Items.Add(Keys.SomeKey, "foo");
fixture.Inject<IViewDataContainer>(new FakeViewDataContainer());
var htmlHelper = fixture.CreateAnonymous<HtmlHelper>();
var sampleModel = fixture.CreateAnonymous<SampleModel>();
//Act
var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();
//Assert
Assert.Equal("<table id=\"foo\"></table>", result);
}
fakehttpcontextとfakeviewdatacontainerは、httpcontextbaseとiviewdatacontainerの偽の実装にすぎません。
このテストは、期待される結果に合格し、返されます。ただし、ここで自動フィクストールを正しく利用しているかどうかはわかりません。このユニットテスト内で自動フィクストールを使用するより良い方法はありますか?
解決
部分情報に基づいて、上記のテストをさらに減らす方法を正確に伝えることは困難ですが、それを減らすことができると思います。
まず第一に、呼び出しのコンボ Inject
に続く CreateAnonymous
かなり慣用的です - 特にシーケンスを逆転させる場合。これは呼ばれます 凍結 匿名の値(そして、DIコンテナのシングルトン生涯範囲に相当)。このように、より簡潔に述べることができます:
var vc = fixture.Freeze<ViewContext>();
また、テストがhttpcontextを偽のhttpcontextにマッピングしているようです。 マッピングは少し簡単に実行できます, 、しかし、それは一時的なインスタンスをマッピングします...
いずれにせよ、使用する説得力のある理由がない限り ダイナミックモックライブラリの代わりに手動モック, 、使用することもできます 自動モッキングコンテナとしての自動フィクストール. 。それはあなたがそのタイプマッピングの多くを取り除くかもしれません。
だから、それをすべて考えると、私は 推測してみて テストをこのようなものに減らすことができるかもしれないこと:
[Fact]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
//Arrange
var vc = fixture.Freeze<ViewContext>();
vc.HttpContext.Items.Add(Keys.SomeKey, "foo");
var htmlHelper = fixture.CreateAnonymous<HtmlHelper>();
var sampleModel = fixture.CreateAnonymous<SampleModel>();
//Act
var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();
//Assert
Assert.Equal("<table id=\"foo\"></table>", result);
}
ただし、アレンジパーツのほとんどは純粋に宣言的であり、すでにXunit.netを使用しているように見えるので、使用できます オートフィクストールのオートダタ理論 ほとんどの変数をメソッド引数に移動するには:
[Theory, AutoMoqData]
public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml(
[Frozen]ViewContext vc,
HtmlHelper htmlHelper,
SampleModel sampleModel)
{
//Arrange
vc.HttpContext.Items.Add(Keys.SomeKey, "foo");
//Act
var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();
//Assert
Assert.Equal("<table id=\"foo\"></table>", result);
}
これは、あなたがこのようなオートダタトリブを備えて自動的に顧客化することを橋渡ししたことを前提としています。
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute :
base(new Fixture().Customize(new AutoMoqCustomization()))
{ }
}
上記のコードを少し調整して、APIの詳細に適合させる必要がある場合があることに留意してください。これはスケッチとしてのみ意味されます。