C# 用于单元测试的存根ASP.NET页.Form
对于单元测试ASP.NET控件,我需要一个存根页面 我可以通过子类化System.Web.UI.Page在单元测试中创建ASP.NET页面对象。 但是,我找不到设置Page.Form的方法。添加具有属性(runat、server)的表单 不起作用。在我的子类中重载表单不会提供所需的功能 背景: 我尝试对一些自制的ASP.NET控件进行单元测试。这些控件要求Page和Page.Form不为nullC# 用于单元测试的存根ASP.NET页.Form,c#,.net,asp.net,vb.net,unit-testing,C#,.net,Asp.net,Vb.net,Unit Testing,对于单元测试ASP.NET控件,我需要一个存根页面 我可以通过子类化System.Web.UI.Page在单元测试中创建ASP.NET页面对象。 但是,我找不到设置Page.Form的方法。添加具有属性(runat、server)的表单 不起作用。在我的子类中重载表单不会提供所需的功能 背景: 我尝试对一些自制的ASP.NET控件进行单元测试。这些控件要求Page和Page.Form不为null 有什么建议吗?尝试定义一个IPage和IForm接口,实现所需的方法和属性,创建实现这些接口的类,并
有什么建议吗?尝试定义一个
IPage
和IForm
接口,实现所需的方法和属性,创建实现这些接口的类,并包装一个页面
或表单
类。通过这种方式,您可以测试这些控件中的逻辑,而无需在单元测试期间调用ASP.NET framework
更新:
重写页面属性将很脆弱,不建议这样做。相反,您应该通过在不依赖于任何ASP.NET特定(难以测试)部分的方法中提取逻辑来尽量减少不稳定代码的数量。请看以下示例:
public class MyLabel : Label
{
protected override override void RenderContents(HtmlTextWriter writer)
{
IPage page = new PageWrapper(this.Page);
this.MethodToTest(page);
base.RenderContents(writer);
}
internal void MethodToTest(IPage page)
{
// Work with IPage interface.
if (page.IsPostBack)
{
this.Text = string.Empty;
}
}
}
通过从难以测试的方法中提取逻辑,您可以在测试中直接调用这些提取的方法。例如:
[TestMethod]
public void MethodToTest_ScenarioToTest_ExpectedBehavior()
{
// Arrange
var label = new MyLabel();
var page = new TestPage()
{
IsPostBack = true
};
// Act
label.MethodToTest(page);
// Assert
Assert.IsTrue(string.Empty, label.Text);
}
如果您能够将测试中的代码提取到它自己的类中,并从您的WebControl调用它,那就更好了。然而,这并不总是可能的
我希望这是有意义的。你到底想测试什么?如果您正在测试的内容不完全依赖于页面本身,那么您可以完全避免需要页面实例,从而节省很多心痛。请看以下链接: 但是,如果您要测试的内容确实取决于page类,请使用您自己的类包装它,该类提供对数据的访问方法。然后将该类转换为接口,用作方法或构造函数的参数 例如:
public testPageNull_shouldThrowArgumentNullException()
{
PageWrappable nullPage = new MockPageWrappable();
nullPage.GetPage().Return(null);
CustomControl sut = new CustomControl(nullPage);
Assert.Fail("Exception not thrown");
}
public interface PageWrappable
{
//Gets Wrapped Page Instance
WrappedPage GetPage();
//GetSomethingFromTheForm
String GetFormValue(String Key);
}
几年前,我在ASP.NET中遇到了同样的问题,我们实现了,并设法对所有逻辑进行了单元测试(并将非常愚蠢的视图的测试留给了手动测试)。我使用的控件继承自System.Web.UI.WebControl.LabelOur类继承自System.Web.UI.Control,该类实现了Page属性。您的建议要求我覆盖te Page属性并添加IPage的Page2属性?我喜欢您的pagewrapper方法。我仍然必须决定如何使IPage对象可用于我的方法。我想我会使用构造函数注入到受保护的或私有的属性中。这正是我所做的。我们使用被动视图,但控制器从存储在模型中的视图组件获取名称/值对。当然,在过去,时间/焦点不允许进行单元测试。现在,我用单元测试记录控件属性的行为,并添加了一个测试,通过将生成的字符串加载到linq XElement中来查看呈现的html是否格式良好,并查看是否会出现异常。在这一部分中,我们对Page.form有一个实际不需要的硬依赖关系。我要用史蒂文的解决方案来解决这个问题。