3

多数のASP.Netサーバーコントロールを開発しており、それらをテストする必要があります。コントロールをインスタンス化し、いくつかのプロパティを設定し、CreateChildControlsを呼び出して、コントロール階層をテストしたいと思います。

私はいくつかの問題に遭遇します:

  1. コントロールはHttpContextに依存しています
  2. CreateChildControlsはプライベートです

コントロールコレクションに単一の子コントロールを追加する場合でも、HttpContextに依存するResolveAdapter()メソッドを呼び出します。

どうすればこれを回避できますか?

psページのコントロールをテストしたくありません(!)。

4

1 に答える 1

1

コントロールの実際のレンダリングはまったく気にしないように聞こえますが、コントロールに含まれるロジックは気にしません。そのためには、HttpContextの外部でコントロールをテストできないこと以外に別の問題があることをお勧めします。

ロジックがコントロールにのみ関係する場合は、フレームワークがその仕事をすることを信頼し、コントロールをページにドロップして、正しく機能するかどうかを確認する必要があります。テストしようとしているロジックがビジネスロジックである場合は、リファクタリングする必要があります。

ビジネスロジックを別のProject/Dllに引き出し、サーバーコントロールを使用してMVPパターンを実装することを検討してください。WCSFのような大きくて重いフレームワークを使用する必要もありません。概念的には、これを少しの労力で実装できます。

ビューの値を表すインターフェースを作成します。

public interface IOrderView
{
    Int32 ID{get; set;}
    String Name{get; set;}
    List<Item> Items {set;}
}

これが定義されたら、このビューを実行するプレゼンターが必要です。

public class OrderPresenter
{
    public IOrderView View {get; set;}

    public void InitializeView()
    {
        //Stuff that only happens when the page loads the first time

        //This is only for an example:
        var order = Orders.GetOrder(custId);

        View.ID = order.ID;
        View.Name = order.Name;
        View.Items = order.Items;
    }

    public void LoadView()
    {
        //Stuff that happens every page load
    }
}

これで、サーバーコントロールはこのインターフェイスを実装し、OrderPresenter

public class OrderControl: Panel, IOrderView
{
    private OrderPresenter Presenter{get; set;}

    public OrderControl()
    {
        //Create new presenter and initialize View with reference
        // to ourselves
        Presenter = new OrderPresenter{View = this;}
    }

    protected override void OnLoad(EventArgs e)
    {
        if(Page.IsPostback)
        {
            _presenter.InitializeView();
        }

        _presenter.LoadView();

        //Other normal onload stuff here...
    }

    //Now for the interface stuff
    public Int32 ID
    {
        get{ return Int32.Parse(lblOrderId.Text); } 
        set{ lblOrderId.Text = value.ToString(); }
    }

    public String Name
    {
        get{ return lblOrderName.Text; } 
        set{ lblOrderName.Text = value; }
    }

    public List<Item> Items 
    {
        set
        {
            gvItems.DataSource = value;
            gvItems.DataBind();
        }
    }
}

そして、あなたはそれを持っています!スタブアウトされたビューを使用して、OrderPresenterに対する単体テストを記述できるはずです。HttpContextは不要であり、関心の分離がより明確になります。

すでにすべてのビジネスロジックを分離している場合は、申し訳ありませんが、実際のビジネスロジックを検証する必要がある以外に、ASP.Netランタイムの外部でサーバーコントロールをテストする他の理由は考えられません。この場合、メンテナンスの悪夢が最終的にLeaky Abstractionsを介して発生することに気付く前に、今すぐリファクタリングすることを強くお勧めします。

于 2009-06-10T11:24:38.583 に答える