如何测试Asp.Net MVC视图是否无异常地渲染?

6

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

我将主要应用程序的命名空间从MyApp.Models更改为MyApp.ViewModels,以便整个命名空间更加清晰易懂(因为该命名空间仅包含视图模型而不是业务模型)。我更改了所有可以找到的引用,包括视图,在重新运行了所有单元测试并检查了应用程序之后,一切似乎都很好。

几天后,有人报告说注册页面在打开时出现错误。经过查看发现,我忘记修复注册页面上的命名空间,因此它无法编译视图。

这让我感到担忧。单元测试的整个目的,以及Asp.Net MVC最大的吸引力之一,就是通过自动单独测试所有内容来使您对应用程序充满信心,以便您知道修改何时会破坏系统的某些部分。当前,视图似乎是一个重要的漏洞。

明确一下,我知道您可以启用预编译视图。但是,我不喜欢这个选项,因为随时启用它并不是一个好主意(因为这会使编译新构建非常缓慢),并且具有单独的配置方案意味着用户需要记住尝试使用该配置方案来检查视图编译错误。

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

在视图中可能导致运行时异常的其他代码示例包括不正确的循环(可能是由于视图模型的更改引起的),检查用户角色的代码(因此只为具有凭据的用户显示按钮),不正确的转换(例如将集合转换为选择列表),不正确的代码以对集合进行排序(如何在显示中对集合进行排序可以被视为视图问题,而不是控制器或视图模型问题),如果用于文件位置的字符串无法正常工作(T4MVC与某些事物(例如Telerik的脚本注册系统)集成得不好)等等……

在渲染视图的过程中,有许多因素可能导致异常发生,我似乎找不到任何方法来创建单元测试或集成测试以确定何时发生这些异常。如果我不得不检查每个页面以确保我没有错过标准单元测试应该能够捕获的编译时或运行时错误的内容,我会感到更加安心。

我有什么选项可以做到这一点呢?

我更倾向于避开WaTiN和其他GUI测试工具,因为我对页面的实际显示不感兴趣,我只想知道视图是否渲染或是否出现异常,并且不需要Watin为每个测试运行IE实例的额外开销(我也认为如果稍后采用持续集成,这将导致问题)。

2个回答

3
如果您不想使用 WaTIN 和 IE,那么可以在 IIS Express 中启动您的网站,然后使用 HttpWebRequest 请求每个页面的 URL,以检查结果是否为 200 OK。这是一个完整的集成测试。
否则,您需要从控制器获取 ViewResult,并调用 ExecuteResult 方法,传入一个包含模拟 HttpContextBaseControllerContext。这会更接近真正的单元测试,并且速度会更快,但在工作之前需要进行大量的模拟和存根。

啊,我没有注意到ViewResult上的ExecuteResult方法。我会研究一下的! - KallDrexx
在深入尝试对ViewResult.ExecuteResult()进行单元测试之后,我已放弃。ViewResult.FindView()代码中的某些内容在框架深处引发了空引用异常。我猜你的第一个选择是最好的(或最容易实现的)。我在http://www.reimers.dk/blogs/jacob_reimers_weblog/archive/2010/11/10/testing-your-web-application-with-iis-express-and-unit-tests.aspx找到了执行此操作的代码。 - KallDrexx
真倒霉。我有一种感觉,尝试了却失败了。ASP.NET不适合进行模拟测试。我一直使用简单的WaTIN测试,但如果你只需要一个简单的成功/失败测试,HttpWebRequestHttpClient应该很适合你。 - Tim Rogers
是的,看起来是这样。尽管当涉及表单身份验证时,HttpWebRequests似乎会很困难。我会暂时不做任何操作。 - KallDrexx

1

这些测试似乎是为了检查控制器是否使用特定的模型类型调用视图,但没有检查视图是否实际上期望该模型。 - KallDrexx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接