MvcIntegrationTestFramework 或针对 ASP.NET MVC 3 更新的替代方案

发布于 2024-10-04 14:16:07 字数 1339 浏览 2 评论 0原文

我有兴趣使用 Steve Sanderson 的 MvcIntegrationTestFramework 或与 ASP.NET MVC 3 Beta 非常相似的替代方案

目前,在针对 MVC 3 Beta 编译 MvcIntegrationTestFramework 时,由于 MVC 中的更改,我收到以下错误:

错误 6 'System.Web.Mvc.ActionDescriptor.GetFilters()' 已过时:'“请立即调用 System.Web.Mvc.FilterProviders.Providers.GetFilters()。”'' \MvcIntegrationTestFramework\ Interception\InterceptionFilterActionDescriptor.cs 第 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()并没有快速实现任何目标,只需添加[已过时] 发现 MVC 请求的内部存在错误。还有其他人涉足过吗?

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

I'm interested in using Steve Sanderson’s MvcIntegrationTestFramework or a very similar alternative with ASP.NET MVC 3 Beta.

Currently when compiling MvcIntegrationTestFramework against MVC 3 Beta I get the following error due to changes in 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

Questions

  1. Can anybody provide the MvcIntegrationTestFramework working for ASP.NET MVC 3 Beta?

--- and / or ---

  1. Are there similar alternatives you would recommend?

EDIT #1: Note I have e-mailed Steve the creator of MvcIntegrationTestFramework, also hoping for some feedback there.

EDIT #2 & #3: I have received a message from Steve. Quoted for your reference:
I haven't needed to use that project with MVC 3, so sorry, I don't have an updated version of it. As far as I'm aware it should be possible to update it to work on MVC 3, but you'd need to figure that out perhaps by inspecting the MVC 3 source code to notice any changes in how actions, filters, etc are invoked now. If you do update it, and if you decide to adopt it as an ongoing project (e.g., putting it on Github or similar), let me know and I'll post a link to it! (Thanks Steve!)

EDIT #4: Honestly had a quick stab at using System.Web.Mvc.FilterProviders.Providers.GetFilters() didn't get anywhere fast and simply adding the [Obsolete] found that there was an error in the internals of the MVC requests. Anybody else had a dabble?

EDIT #5: Please comment if you are using an alternative Integration Test Framework with MVC 3.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空‖城人不在 2024-10-11 14:16:07

我意识到这不是您正在寻找的答案,但 Selenium 或 Watin 可能对您有用,作为集成测试框架的替代方案。

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

需要注意的是,Selenium 需要将您的应用程序部署在 Web 服务器上,不确定这是否对您来说是一个障碍。

I realize this is not the answer you're looking for but Selenium or Watin may be of use to you as an alternative to the Integration Test Framework.

Selenium will let you record tests as nUnit code so you can integrate with your existing test projects etc. Then your test can validate the DOM similarly to the Integration Test Framework. The advantage is Selenium tests can be executed with various different browsers.

Key caveat is that Selenium needs your app to be deployed on a web server, not sure if that's a show stopper for you.

羅雙樹 2024-10-11 14:16:07

我想分享我在 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 角色项目的 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 缓存机制)。也就是说,我还没有遇到任何与此相关的问题,尽管我也还没有真正编写那么多集成测试......

I thought I would share my experiences with using MvcIntegrationTestFramework in an ASP.NET MVC 4 project. In particular, the ASP.NET MVC 4 project was a Web Role for a Windows Azure Cloud Service.

Although the example project from Jon Canning's fork worked for me (although I did change the System.Web.Mvc assembly from 3.0.0.0 to 4.0.0.0, which required a bunch of editing in the web.config file to get the tests to run and pass), I got an error whenever I tried to run the same tests against an Azure ASP.NET MVC 4 Web Role project. The error was:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.

The inner exception was:

System.InvalidOperationException: This method cannot be called during the application's pre-start initialization phase.

I started wondering how an Azure Web Role project based on ASP.NET MVC 4 was different to a normal ASP.NET MVC 4 project, and how such a difference would cause this error. I did a bit of searching on the web but didn't come across anybody trying to do the same thing that I was doing. Soon enough I managed to realise that it was to do with the Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener. Part of the role of this class seems to be to ensure that the web role is running in a hosted service or the Development Fabric (you'll see a message to this effect if you switch the startup project from the cloud service project to the web role project inside a cloud service solution, and then try to debug).

The solution? I removed the corresponding listener from the Web.config file of my Web Role project:

<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>

I was then able to run integration tests as normal against my Web Role project. I did, however, add the listener to the Web.Debug.config and Web.Release.config transformation files so that everything was still the same for normal deploying and debugging.

Maybe that will help somebody looking to use the MvcIntegrationTestFramework for Azure development.

EDIT
I just realised that this solution might be a bit of a 'hack' because it might not let you do integration testing on application code that relates to Azure components (e.g. the special Azure caching mechanisms perhaps). That said, I haven't come across any issues to do with this yet, although I also haven't really written that many integration tests yet either...

南街女流氓 2024-10-11 14:16:07

我使用了 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 个键,而是只有 3 个键,其中之一是一个包含 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);             
        }

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

I used Jon Canning's updated version (https://github.com/JonCanning/MvcIntegrationTestFramework/) and it solved my problem very well for controller methods that only accept value types and strings, but did not work for those that accepted classes.

It turns out there was an issue with the code for the updated MvcIntegrationTestFramework.

I figured out how to fix it, but don't know where else to post the solution, so here it is:

A simple sample to show how it works is:

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

The call to browsingSession.Post would ultimately cause the NameValueCollectionConversions.ConvertFromRouteValueDictionary(object anonymous) method to be called, and the code for that was:

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

Then there was two problems:

  1. The call to new RouteValueDictionary(anonymous) would cause the "new" RouteValueDictionary to be created, but instead of 4 keys, there are only three, one of which was an array of 4 items.
  2. When it hits this line: nvc.Add(kvp.Key, kvp.Value.ToString(), the kvp.Value is an array, and the ToString() gives:
    "System.Collections.Generic.Dictionary'2+ValueCollection[System.String,System.Object]"

The fix (to my specific issue) was to change the code as follows:

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

After I made this change, then my model class would properly bind, and all would be well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文