将ASP.NET Page.Form存储为单元测试

时间:2011-02-22 14:13:29

标签: c# .net asp.net vb.net unit-testing

Fo单元测试ASP.NET控件我需要一个存根页面。

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

上下文: 我尝试对一些自制的ASP.NET控件进行单元测试。这些控件需要Page和Page.Form不能为空。

有什么建议吗?

3 个答案:

答案 0 :(得分:3)

尝试定义实现所需方法和属性的IPageIForm接口,并创建实现这些接口的类并包装PageForm类。这样,您可以测试这些控件中的逻辑,而无需在单元测试期间调用ASP.NET框架。

<强>更新

覆盖页面属性会很脆弱,不建议这样做。相反,您应该尝试通过在不依赖于任何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中调用它,那就更好了。然而,这并非总是可行。

我希望这是有道理的。

答案 1 :(得分:1)

你到底想要测试什么?如果您正在测试的内容并不完全依赖于页面本身,那么您可以避免需要一个页面实例来完全为自己节省很多心痛。请看以下链接:

http://xunitpatterns.com/Humble%20Object.html

但是,如果您要测试的内容确实取决于页面类,请使用您自己的类来包装它,该类提供对数据的访问方法。然后将该类转换为接口,以用作方法或构造函数的参数。

示例:

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);
}

答案 2 :(得分:0)

几年前,我遇到了与ASP.NET相同的问题,我们实现了Fowler's «Passive View» pattern,并设法对所有逻辑进行单元测试(并将相当愚蠢的视图的测试留给了手动测试)。