如何测试 Asp.Net MVC 视图是不是无例外地呈现?

Posted

技术标签:

【中文标题】如何测试 Asp.Net MVC 视图是不是无例外地呈现?【英文标题】:How do I test that Asp.Net MVC Views are rendered without exceptions?如何测试 Asp.Net MVC 视图是否无例外地呈现? 【发布时间】:2011-05-16 19:41:40 【问题描述】:

我在我的应用程序中遇到了一个小问题。

我将主应用程序的命名空间从 MyApp.Models 更改为 MyApp.ViewModels,这样命名空间整体上就不那么混乱了(因为该命名空间只有视图模型而没有业务模型)。我更改了我能找到的所有参考资料,包括我的视图,我重新运行了所有单元测试并检查了应用程序,一切看起来都很好。

几天后,我收到报告说注册页面在启动时出现错误。看了之后发现我忘了修复注册页面上的命名空间,因此编译视图失败。

这让我很担心。单元测试的重点,也是 Asp.Net MVC 的最大诱惑之一,是能够通过自动对所有内容进行单独测试来对您的应用程序充满信心,这样您就可以立即知道您的修改何时会破坏系统的某些部分。现在的观点似乎是其中的一个主要漏洞。

明确地说,我知道您可以打开预编译视图。但是,我不喜欢这个选项,因为一直使用它并不是一个好主意(因为它使编译新版本非常非常慢),并且为此有一个单独的配置方案意味着它取决于用户请记住尝试使用该配置方案进行编译以检查视图编译错误。

这也完全绕过了对可能发生的运行时错误的检查。例如,假设您更改了强类型视图所期望的视图模型。然后,您将更新单元测试以确保 Controller.Action() 返回具有正确视图模型类型的视图结果,但这并不能确保为新视图正确更新了实际视图,但这种情况将导致运行时异常。这是一个很容易发生的情况,尤其是如果两个视图模型的差异仅在视图中使用的部分中可见。

其他可能导致视图运行时异常的代码示例包括不正确的循环(可能由视图模型的更改引起)、检查用户角色的代码(因此按钮仅显示给具有凭据的用户)、不正确的强制转换(例如用于将集合转换为选择列表),对集合进行排序的代码不正确(集合在显示中的排序方式可以解释为视图关注点,而不是控制器或视图模型关注点),如果用于文件位置的字符串不' t 工作正常(T4MVC 不能很好地与某些东西集成,例如 Telerik 的脚本注册系统)等...

在我看来,在渲染视图的过程中有很多事情会导致异常发生,而我似乎找不到任何方法来创建单元或集成测试来确定这些发生的时间。如果我不必检查每个页面以确保我错过了标准单元测试应该能够捕获的编译时间或运行时错误,我会感觉更舒服。

我有哪些选项可以做到这一点?

我宁愿远离WaTiN和其他GUI测试工具,至于这个我对页面的实际显示不感兴趣,我只想知道视图是否渲染或者是否发生异常并且不需要Watin 为每个测试运行一个 IE 实例的开销(我还认为,如果我稍后使用持续集成,这会导致问题)。

【问题讨论】:

【参考方案1】:

如果您不想使用 WaTIN 和 IE,那么如何在 IIS Express 中启动您的网站,然后在每个视图的 URL 上使用 HttpWebRequest 来检查结果是否为 200 OK。这是一个完整的集成测试。

否则,您必须从控制器中获取ViewResult,并调用ExecuteResult 方法,传入包含存根HttpContextBaseControllerContext。这提供了更多真正的单元测试,并且速度更快,但是在它工作之前你需要做很多模拟和存根。

【讨论】:

啊,我没有注意到ViewResult 上的ExecuteResult 方法。我会调查的! 在深入尝试单元测试ViewResult.ExecuteResult() 之后,我放弃了。 ViewResult.FindView() 代码中的某些内容在框架深处提供了空引用异常方式。我猜你的第一个选择是最好的(或最容易实现的)。我在reimers.dk/blogs/jacob_reimers_weblog/archive/2010/11/10/… 找到了执行此操作的代码 运气不好。我有一种我自己尝试过但失败了的感觉。 ASP.NET 并不是为了模拟而构建的。我一直使用简单的 WaTIN 测试,但如果您只需要一个简单的成功/失败测试,​​HttpWebRequestHttpClient 应该很适合您。 是的,看起来是这样。尽管在涉及表单身份验证时,HttpWebRequests 看起来确实很困难。我将暂缓执行任何此操作。【参考方案2】:

mspec mvc extensions

【讨论】:

那些似乎测试控制器正在调用具有特定模型类型的视图,但没有检查视图实际上期望它作为模型。

以上是关于如何测试 Asp.Net MVC 视图是不是无例外地呈现?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET MVC 视图中用 C# 打印出 GridView?

Asp.Net MVC:如何获取当前控制器/视图的虚拟 url?

如何在asp.net mvc中将数据从视图传递到控制器

如何在 ASP.NET MVC 视图中将主键转换为实际名称/描述符字段

我如何检测请求是不是来自我的 asp.net MVC 3 中的移动浏览器

这是错误的,为啥不是? ASP.NET MVC 视图包