Как модульное тестирование лучше в ASP.NET MVC, чем в веб-формах? - PullRequest
14 голосов
/ 15 июля 2010

Я только начал изучать ASP.NET MVC.При сравнении ASP.NET MVC с веб-формами всегда говорят, что одним из главных преимуществ MVC является лучшая поддержка модульного тестирования.Могу ли я получить хорошее объяснение того, как у него улучшена поддержка?

Редактировать: Если возможно, приведите пример в обоих случаях.

Ответы [ 8 ]

12 голосов
/ 16 июля 2010

Asp.Net MVC имеет лучшую поддержку модульного тестирования по одной основной причине - вся архитектура построена на использовании HttpContextBase, HttpRequestBase и HttpResponseBase.

Веб-формы Asp.Net зависят от HttpContext.Current, который является единичным элементом, который вы не можете контролировать - он настраивается и передается на ваши страницы в рамках HttpApplication, выполняющего запрос. В большинстве случаев для правильного выполнения страницы вам нужно выполнить ее в реальном HttpContext. Поскольку многие свойства HttpContext не могут быть установлены (например, «Запрос и ответ»), крайне сложно создать поддельные запросы для отправки на объекты вашей страницы.

Это делает модульное тестирование страниц веб-форм настоящим кошмаром, поскольку все ваши тесты связаны с необходимостью всевозможной настройки контекста.

Сравните это с ASP.Net MVC, где вы можете макетировать HttpContext! Теперь вашему коду даже не нужен веб-сервер для предоставления ему контекста, вы можете просто установить нужные биты и передать проверенный контекст вашему методу.

6 голосов
/ 15 июля 2010

Жизненный цикл страницы ASP.NET невероятно затрудняет юнит-тестирование классов, производных от Page, который начинается с слишком большого количества обязанностей и становится божественным объектом , когда выдобавить логику приложения к нему.Хуже того, он имеет скрытые зависимости от статических классов и требует конструктора по умолчанию без параметров, который ограничивает ваши возможности для внедрения зависимостей.

Итак, чтобы сделать страницу ASP.NET WebForms тестируемой, вам нужно принять всю логикуиз вашего кода и поместите его в другой класс - обычно Presenter , как в Model-View-Presenter шаблон.

Контроллеры ASP.NET MVC уже отделены от своих шаблонов и не обременены жизненным циклом страницы ASP.NET.

4 голосов
/ 15 июля 2010

Поскольку вы можете создать объект контроллера в своем модульном тесте, вызвать некоторые действия с ним и сразу увидеть результат, тогда вы можете Assert.IsBlahBlahBlah(); на нем.

Например,

    [TestMethod]
    public void Index()
    {
        // Arrange
        HomeController controller = new HomeController();

        // Act
        ViewResult result = controller.Index() as ViewResult;

        Assert.IsNotNull(result);
    }

С этим методом вы теперь знаете, что ваше представление индекса возвращается из контроллера Home.

3 голосов
/ 18 июля 2010

Если вы хотите использовать ASP.Net WebForms (как я) и модульные тесты вместе, взгляните на это:

WebForms MVP на codeplex

У меня работает.

2 голосов
/ 16 июля 2010

Вы можете сделать то же самое с веб-формами, просто те, кто не знает лучше, пишут код, который не может быть протестирован таким образом.

Нет причин иметь бизнес-логику в классе codebehind. То же самое с логикой доступа к данным. Даже здесь, это позволяет вам тестировать части приложения, наиболее подверженные как ошибкам, так и тестированию.

Некоторые могут сказать, что это не позволяет вам проверять нажатия кнопок и другие события пользовательского интерфейса. Если вы хотите сделать это, то вы можете создать свой собственный MVC или MVP или другой подобный шаблон, который использует отдельный интерфейс для действий пользовательского интерфейса. Затем выполните точно такой же тест, как и при использовании ASP.NET MVC.

А у вас все еще есть проблема невозможности протестировать код на стороне клиента.

2 голосов
/ 15 июля 2010

Гораздо сложнее тестировать код позади страницы, чем тестировать контроллер. В шаблоне MVC существует более логичное разделение логики представления, что облегчает написание тестов.

1 голос
/ 02 августа 2010

Что касается предложения Лоуренса о Селене, есть также WatiN .

Это не относится к MVC, но я думаю, что MVC определенно помогает в том, что он поддерживает чистоту идентификаторов элементов и классови легче нацеливаться из теста.

С WatiN вы можете сделать следующее (пример с их сайта).

[Test]
public void SearchForWatiNOnGoogle()
{
 using (var browser = new IE("http://www.google.com"))
 {
  browser.TextField(Find.ByName("q")).TypeText("WatiN");
  browser.Button(Find.ByName("btnG")).Click();

  Assert.IsTrue(browser.ContainsText("WatiN"));
 }
}
1 голос
/ 20 июля 2010

Немного ОТ, но вы можете посмотреть на Selenium для модульных веб-страниц тестирования ...

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