Заглушка ASP.NET Page.Form для модульных тестов - PullRequest
8 голосов
/ 22 февраля 2011

Для модульного тестирования элементов управления ASP.NET Мне нужна заглушка Page.

Я могу создать объект ASP.NET Page в своих модульных тестах, создав подкласс System.Web.UI.Page. Тем не менее, я не могу найти способ установить Page.Form. Добавление формы с атрибутом (runat, server) не работает. Перегрузка формы в моем подклассе не дает необходимой функциональности.

Контекст: Я пытаюсь провести модульное тестирование некоторых самодельных элементов управления ASP.NET. Эти элементы управления требуют, чтобы Page и Page.Form не были нулевыми.

Есть предложения?

Ответы [ 3 ]

3 голосов
/ 22 февраля 2011

Попробуйте определить интерфейс IPage и IForm, который реализует необходимые методы и свойства, и создайте классы, которые реализуют эти интерфейсы и обернут класс Page или Form.Таким образом, вы можете проверить логику в этих элементах управления, не обращаясь к платформе 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 голос
/ 24 февраля 2011

Что именно вы пытаетесь проверить?Если то, что вы тестируете, не полностью зависит от самой страницы, может быть, вы можете избежать необходимости в экземпляре страницы, полностью экономя душевные страдания.Взгляните на следующую ссылку:

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);
}
0 голосов
/ 25 февраля 2011

У меня была такая же проблема с ASP.NET несколько лет назад, и мы реализовали паттерн Фаулера «Пассивное представление» , и сумели провести модульное тестирование всей логики (и оставили тесты довольно тупые взгляды на ручное тестирование).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...