Подтвердить что ты не робот

MvcIntegrationTestFramework или альтернатива, обновленная для ASP.NET MVC 3

Мне интересно использовать Steve Sandersons MvcIntegrationTestFramework или очень похожая альтернатива с помощью ASP.NET MVC 3 Beta.

В настоящее время при компиляции MvcIntegrationTestFramework против MVC 3 Beta я получаю следующую ошибку из-за изменений в MVC:

Error 6 'System.Web.Mvc.ActionDescriptor.GetFilters()' is obsolete: '"Please call System.Web.Mvc.FilterProviders.Providers.GetFilters() now."' \MvcIntegrationTestFramework\Interception\InterceptionFilterActionDescriptor.cs Line 18

Вопросы

1. Может ли кто-нибудь предоставить MvcIntegrationTestFramework для бета-версии ASP.NET MVC 3?

--- и/или ---

2. Есть ли аналогичные альтернативы, которые вы бы рекомендовали?


РЕДАКТИРОВАТЬ № 1: Примечание. Я отправил по электронной почте Стив, создатель MvcIntegrationTestFramework, также надеясь на некоторую обратную связь.

EDIT # 2 и # 3: Я получил сообщение от Стива. Цитируется по ссылке:
Мне не нужно было использовать этот проект с MVC 3, так что извините, у меня нет обновленной версии. Насколько мне известно, должно быть возможно обновить его для работы с MVC 3, но вам нужно будет понять это, возможно, проверив исходный код MVC 3, чтобы заметить какие-либо изменения в действии действий, фильтров и т.д. Теперь. Если вы его обновите, и если вы решите принять его в качестве текущего проекта (например, положив его на Github или аналогичный), сообщите мне, и я отправлю ему ссылку! (Спасибо Стив!)

РЕДАКТИРОВАТЬ № 4: Честно быстрая атака при использовании System.Web.Mvc.FilterProviders.Providers.GetFilters() не ускорилась и просто добавила [Obsolete], что была ошибка во внутренних сообщениях MVC-запросов, У кого-нибудь еще была ошибка?

РЕДАКТИРОВАТЬ № 5: Прокомментируйте, если вы используете альтернативную тестовую платформу интеграции с MVC 3.

4b9b3361

Ответ 2

Я понимаю, что это не тот ответ, который вы ищете, но Selenium или Watin могут вам пригодиться в качестве альтернативы Integration Test Framework.

Selenium позволит вам записывать тесты как код nUnit, чтобы вы могли интегрироваться с существующими тестовыми проектами и т.д. Затем ваш тест может проверить DOM аналогично Framework Integration Test Framework. Преимущество Selenium-тестов может быть выполнено с различными браузерами.

Предостережение о том, что Selenium необходимо, чтобы ваше приложение было развернуто на веб-сервере, не уверен, что это шоу-стоп для вас.

Ответ 3

Я думал, что поделился бы опытом использования MvcIntegrationTestFramework в проекте ASP.NET MVC 4. В частности, проект ASP.NET MVC 4 был веб-ролью для облачной службы Windows Azure.

Хотя проект проекта из вилки Джона Коннинга работал у меня (хотя я изменил сборку System.Web.Mvc от 3.0.0 до 4.0.0.0, что потребовало кучу редактирования в файле web.config, чтобы получить тесты для запуска и передачи), я получил сообщение об ошибке, когда пытался запустить те же тесты с проектом Azure ASP.NET MVC 4 Web Role. Ошибка:

System.Reflection.TargetInvocationException: Исключение выбрано целевым объектом вызова.

Внутреннее исключение:

System.InvalidOperationException: этот метод не может быть вызван во время фазы инициализации перед запуском приложения.

Мне стало интересно, как проект Azure Web Role на основе ASP.NET MVC 4 отличается от обычного проекта ASP.NET MVC 4 и как такая разница может вызвать эту ошибку. Я немного искал в Интернете, но не сталкивался с тем, что кто-то пытался сделать то же самое, что и я. Вскоре я понял, что это связано с Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener. Часть роли этого класса, по-видимому, заключается в обеспечении того, чтобы роль веб-сайта выполнялась в размещенной службе или в Fabric Development (вы увидите сообщение об этом, если вы переключите проект запуска из проекта облачной службы на веб-сайт ролевой проект внутри облачного сервисного решения, а затем попытайтесь отладить).

Решение? Я удалил соответствующий прослушиватель из файла Web.config проекта моей веб-роли:

<configuration>
... 
  <system.diagnostics>
    <trace>
      <listeners>
        <!--Remove this next 'add' element-->
        <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      name="AzureDiagnostics"> <filter type="" /> </add> 
      </listeners>
    </trace>
  </system.diagnostics>
...
</configuration>

Затем я смог выполнить интеграционные тесты как обычно против моего проекта веб-роли. Однако я добавил слушателя в файлы преобразования Web.Debug.config и Web.Release.config, чтобы все было по-прежнему одинаковым для обычного развертывания и отладки.

Возможно, это поможет кому-то, кто хочет использовать MvcIntegrationTestFramework для разработки Azure.

ИЗМЕНИТЬ Я просто понял, что это решение может быть немного "взломанным", потому что это может не позволить вам протестировать интеграцию с кодом приложения, который относится к компонентам Azure (например, могут использоваться специальные механизмы кэширования Azure). Тем не менее, я еще не сталкивался с какими-либо проблемами, хотя я еще не писал, что многие интеграционные тесты еще...

Ответ 4

Я использовал обновленную версию Jon Canning (https://github.com/JonCanning/MvcIntegrationTestFramework/), и она решила мою проблему очень хорошо для методов контроллера, которые принимают только типы значений и строки, но не работал для тех, кто принял классы.

Оказывается, возникла проблема с кодом обновленного MvcIntegrationTestFramework.

Я выяснил, как это исправить, но не знаю, где еще разместить сообщение, так что вот оно:

Простой пример, показывающий, как он работает:

    [TestMethod]
    public void Account_LogOn_Post_Succeeds()
    {
        string loginUrl = "/Account/LogOn";
        appHost.Start(browsingSession =>
        {
            var formData = new RouteValueDictionary
            {
                { "UserName", "myusername" },
                { "Password", "mypassword" },
                { "RememberMe", "true"},
                { "returnUrl", "/myreturnurl"},
            };

            RequestResult loginResult = browsingSession.Post(loginUrl, formData);

            // Add your test assertions here.
        });
    }

Вызов browsingSession.Post в конечном итоге приведет к вызову метода NameValueCollectionConversions.ConvertFromRouteValueDictionary(object anonymous), а код для этого:

public static class NameValueCollectionConversions
{
    public static NameValueCollection ConvertFromObject(object anonymous)
    {
        var nvc = new NameValueCollection();
        var dict = new RouteValueDictionary(anonymous); // ** Problem 1

        foreach (var kvp in dict)
        {
            if (kvp.Value == null)
            {
                throw new NullReferenceException(kvp.Key);
            }
            if (kvp.Value.GetType().Name.Contains("Anonymous"))
            {
                var prefix = kvp.Key + ".";
                foreach (var innerkvp in new RouteValueDictionary(kvp.Value))
                {
                    nvc.Add(prefix + innerkvp.Key, innerkvp.Value.ToString());
                }
            }
            else
            {
                nvc.Add(kvp.Key, kvp.Value.ToString()); // ** Problem2
            }
        }
        return nvc;
    }

Тогда возникли две проблемы:

  • Вызов new RouteValueDictionary(anonymous) приведет к созданию "нового" RouteValueDictionary, но вместо 4 ключей будет только три, один из которых представляет собой массив из 4 элементов.
  • Когда он попадает в эту строку: nvc.Add(kvp.Key, kvp.Value.ToString(), kvp.Value является массивом, а ToString() дает: "System.Collections.Generic.Dictionary'2+ValueCollection[System.String,System.Object]"

Исправление (по моей конкретной проблеме) заключалось в том, чтобы изменить код следующим образом:

        var dict = anonymous as RouteValueDictionary; // creates it properly
        if (null == dict)
        {
            dict = new RouteValueDictionary(anonymous);             
        }

После того, как я сделал это изменение, мой класс модели будет правильно привязан, и все будет хорошо.