3

我们开发了许多 ASP.Net 服务器控件,我们需要对其进行测试。我想实例化一个控件,设置一些属性,调用 CreateChildControls 并测试控件层次结构。

我遇到了一些问题:

  1. 控件依赖于 HttpContext
  2. CreateChildControls 是私有的

即使将单个子控件添加到控件集合也会调用依赖于 HttpContext 的 ResolveAdapter() 方法。

我怎样才能解决这个问题?

ps 我不想测试页面上的控件(!)。

4

1 回答 1

1

这听起来很像您根本不关心控件的实际呈现,而是控件中包含的逻辑。为此,我建议您除了无法测试 HttpContext 之外的控件之外还有另一个问题。

如果逻辑只与控件有关,那么您应该信任框架来完成它的工作,并将控件放在页面上以查看它是否正常工作。如果您尝试测试的逻辑是业务逻辑,那么您需要重构。

将业务逻辑提取到某个单独的项目/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 回答