我们开发了许多 ASP.Net 服务器控件,我们需要对其进行测试。我想实例化一个控件,设置一些属性,调用 CreateChildControls 并测试控件层次结构。
我遇到了一些问题:
- 控件依赖于 HttpContext
- CreateChildControls 是私有的
即使将单个子控件添加到控件集合也会调用依赖于 HttpContext 的 ResolveAdapter() 方法。
我怎样才能解决这个问题?
ps 我不想测试页面上的控件(!)。
我们开发了许多 ASP.Net 服务器控件,我们需要对其进行测试。我想实例化一个控件,设置一些属性,调用 CreateChildControls 并测试控件层次结构。
我遇到了一些问题:
即使将单个子控件添加到控件集合也会调用依赖于 HttpContext 的 ResolveAdapter() 方法。
我怎样才能解决这个问题?
ps 我不想测试页面上的控件(!)。
这听起来很像您根本不关心控件的实际呈现,而是控件中包含的逻辑。为此,我建议您除了无法测试 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导致的维护噩梦之前进行重构。