2

私は今日の午後の半分を、関連するビットとピースを (MOQ を使用して) モックアップして、次の HtmlHelper を単体テストする方法を見つけようとしました。これは、UrlHelper クラスを使用して img タグを作成します。

    public static IHtmlString Image(this HtmlHelper helper, string id, string url, string alternateText, object htmlAttributes)
    {
        // Instantiate a UrlHelper
        var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);

        // Create tag builder
        var builder = new TagBuilder("img");

        // Create valid id
        builder.GenerateId(id);

        // Add attributes
        builder.MergeAttribute("src", urlHelper.Content(url));
        builder.MergeAttribute("alt", alternateText);
        builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        // Render tag
        return new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing));
    }

誰かがすでに仕事でこの問題を解決しましたか?

4

2 に答える 2

1

最終結果をテストする必要があります。ヘルパーが次のようなものを返す必要があることがわかっている場合は、次のように言いましょう。

<img src="test.jpg" id="testId" alt="something" />

次に、この文字列を実際の結果と比較して、アサーションを行う必要があります。内部でヘルパーを使用しているかどうかは気にする必要はありません。

于 2013-03-17T05:54:04.203 に答える
1

単体テストに適していない .NET 型に遭遇した場合、通常は独自のインターフェイス (必要なメソッドのみを含む) と、メソッド/プロパティ呼び出しを元のクラスに転送するインターフェイスを実装する shim クラスを記述します。シムは検査によってテスト可能です。

次に、このインターフェイスに対して単体テストを行うために必要なすべてのコードを記述します (したがって、具体化ではなく抽象化に依存します)。これには、元の具象型ではなくインターフェイスを拡張する拡張メソッドが含まれます。この点で、拡張メソッドのテストは非常に簡単です。単体テストでの動作を完全に制御できるため、好きなことを何でも実行new Mock<IHtmlHelper>() ...できます。IHtmlHelper

インターフェイスとシムを入力するのは、より大きなインターフェイスを持つクラスでは少し面倒ですが、ほとんどの場合、オーバーヘッドは非常に低いことがわかります。これはまた、物事をテスト可能にするために行う奇妙なトリックが少なくなることを意味します。そのため、私のコードはより一貫性があり、従うのが簡単になります (依存関係は常に同じ方法で注入され、テストは常に同じ方法で記述されます)。

フセイン・ロンセビッチが指摘しているのは、動作ではなく観察可能な状態の観点からクライアントをテストする必要があるということだと思います。HtmlHelperつまり、クライアント コードの単体テストでは、呼び出されたメソッド (拡張メソッドまたはそれ以外) を認識しないようにする必要があります。拡張メソッド自体を単体テストしたいように思えますが、これは完全に合理的なことです。

于 2013-03-18T17:42:50.883 に答える