Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用于单元测试的存根ASP.NET页.Form_C#_.net_Asp.net_Vb.net_Unit Testing - Fatal编程技术网

C# 用于单元测试的存根ASP.NET页.Form

C# 用于单元测试的存根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接口,实现所需的方法和属性,创建实现这些接口的类,并

对于单元测试ASP.NET控件,我需要一个存根页面

我可以通过子类化System.Web.UI.Page在单元测试中创建ASP.NET页面对象。 但是,我找不到设置Page.Form的方法。添加具有属性(runat、server)的表单 不起作用。在我的子类中重载表单不会提供所需的功能

背景: 我尝试对一些自制的ASP.NET控件进行单元测试。这些控件要求Page和Page.Form不为null


有什么建议吗?

尝试定义一个
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有一个实际不需要的硬依赖关系。我要用史蒂文的解决方案来解决这个问题。