【问题标题】:MvcIntegrationTestFramework or an alternative updated for ASP.NET MVC 3MvcIntegrationTestFramework 或为 ASP.NET MVC 3 更新的替代方法
【发布时间】:2010-11-25 15:52:40
【问题描述】:

我有兴趣在 ASP.NET MVC 3 Beta 中使用 Steve Sanderson 的 MvcIntegrationTestFramework或非常类似的替代方法

目前在针对 MVC 3 Beta 编译 MvcIntegrationTestFramework 时,由于 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. 谁能提供适用于 ASP.NET MVC 3 Beta 的 MvcIntegrationTestFramework?

--- 和/或 ---

  1. 您是否会推荐类似的替代方案?

编辑 #1: 请注意,我已经给 MvcIntegrationTestFramework 的创建者 Steve 发送了电子邮件,也希望那里得到一些反馈。

编辑 #2 和 #3: 我收到了史蒂夫的消息。引用供您参考:
我不需要将该项目与 MVC 3 一起使用,很抱歉,我没有它的更新版本。据我所知,应该可以对其进行更新以在 MVC 3 上工作,但您可能需要通过检查 MVC 3 源代码来了解如何调用操作、过滤器等的任何更改现在。如果您确实对其进行了更新,并且您决定将其作为一个正在进行的项目采用(例如,将其放在 Github 或类似网站上),请告诉我,我会发布它的链接!(感谢 Steve!)

编辑 #4: 老实说,使用 System.Web.Mvc.FilterProviders.Providers.GetFilters() 并没有快速获得任何结果,只需添加 [Obsolete] 就发现 MVC 请求的内部存在错误.还有人涉足吗?

编辑#5:如果您正在使用带有 MVC 3 的替代集成测试框架,请发表评论。

【问题讨论】:

  • +1 向我介绍了这个框架。酷。
  • 我正在寻找相同的分辨率。该框架非常有价值。

标签: asp.net-mvc unit-testing integration-testing asp.net-mvc-3


【解决方案1】:

【讨论】:

  • 感谢您的回答 - 标记为正确,因为许多人发现它很有用。但最终我寻找了替代测试方法。
【解决方案2】:

我知道这不是您要寻找的答案,但 Selenium 或 Watin 可能对您有用,作为集成测试框架的替代品。

Selenium 将允许您将测试记录为 nUnit 代码,以便您可以与现有的测试项目等集成。然后您的测试可以验证 DOM,类似于集成测试框架。优点是 Selenium 测试可以在各种不同的浏览器上执行。

需要注意的是,Selenium 需要将您的应用部署在 Web 服务器上,不确定这是否适合您。

【讨论】:

  • 感谢您的回复非常有效和真实。是的,熟悉 Selenium 并且确实有一个测试套件设置,但它不是一个很好的选择。我非常希望在不依赖于浏览器的情况下在类似于 MvcIntergrationTestFramework 的代码中进行“特定级别”的测试。谢谢。
【解决方案3】:

我想我会分享我在 ASP.NET MVC 4 项目中使用 MvcIntegrationTestFramework 的经验。特别是,ASP.NET MVC 4 项目是一个Windows Azure 云服务的Web 角色

虽然 Jon Canning 的 fork 中的示例项目对我有用(尽管我确实将 System.Web.Mvc 程序集从 3.0.0.0 更改为 4.0.0.0,这需要在 web.config 文件中进行大量编辑才能获得测试运行并通过),每当我尝试对 Azure ASP.NET MVC 4 Web 角色项目运行相同的测试时,都会出现错误。错误是:

System.Reflection.TargetInvocationException:调用的目标已抛出异常。

内部异常是:

System.InvalidOperationException:在应用程序的预启动初始化阶段无法调用此方法。

我开始想知道基于 ASP.NET MVC 4 的 Azure Web Role 项目与普通的 ASP.NET MVC 4 项目有何不同,以及这种差异会如何导致此错误。我在网上做了一些搜索,但没有遇到任何人试图做和我一样的事情。很快我就意识到它与 Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener 有关。此类的部分角色似乎是确保 Web 角色在托管服务或 Development Fabric 中运行(如果您将启动项目从云服务项目到云服务解决方案里面的web角色项目,然后尝试调试)。

解决方案?我从我的 Web Role 项目的 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 角色项目正常运行集成测试了。但是,我确实将侦听器添加到 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;
        }
    

    然后有两个问题:

    1. new RouteValueDictionary(anonymous) 的调用将导致创建“新”RouteValueDictionary,但不是 4 个键,而是只有三个键,其中一个是包含 4 个项目的数组。
    2. 当它到达这一行时: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);             
            }
    

    在我进行此更改后,我的模型类将正确绑定,一切都会好起来的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 2010-11-19
      • 1970-01-01
      相关资源
      最近更新 更多