MVC Web 应用程序中的控制器是否应该进行单元测试?
在我看来,不同编程语言的 Web 开发人员经常对此有不同的看法。例如,Ruby Web 开发人员(Rails 是主导框架)似乎将控制器视为粘合代码,应该进行功能测试,而不是单元测试。类似的态度在 PHP 世界中占主导地位,但也出现了一些举措(例如 Symfony2)。
然而,例如,一些 ASP.NET MVC 开发人员实际上似乎想要他们的控制器 可进行单元测试。
我想知道这是否真的适用于网络开发。控制器值得进行单元测试吗?将它们设计为可单元测试是否会明显削弱重要应用程序的开发速度?另外,是否有任何 Web 框架尝试强制控制器单元可测试性?欢迎个人经历。
It seems to me that web developers of different programming languages often share different opinions on this. For example, Ruby web developers (with Rails being the dominant framework) appear to think of controllers as glue code, which should have functional tests, but not unit tests. A similar attitude dominates in the PHP world, yet there has been some initiative (e.g. Symfony2).
However, it also seems that, for example, some ASP.NET MVC developers actually want their controllers to be unit-testable.
What I'd like to know is if that actually works in web development. Are controllers worth unit testing? Does designing them to be unit-testable noticeably cripple development speed in non-trivial applications? Also, have any web frameworks tried to enforce controller unit-testability? Personal experiences are welcome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
简短的回答:“是”,带“如果”,长的回答:“否”,带“但是”。
如今,我倾向于怀念控制器级单元测试,而倾向于对模型和业务对象进行强大的单元测试覆盖,以及使用 Cucumber 进行功能测试覆盖。这里的假设是控制器是非常轻量级的对象,将数据路由到封装绝大多数业务逻辑的底层模型中。
然而,我仍然倾向于对控制器级别的一些控制流进行一些非常简单的介绍。它只是更像是一种健全性检查。
控制器级测试的问题之一是,您通常必须模拟或生成大量模型和对象才能有效进行测试。鉴于此,我发现将这些测试推入功能层更有价值,其中测试风格允许您更有效地表达这些依赖关系(通过明确遵循通过应用程序本身或通过类似系统生成它们所需的步骤) Cucumber 的声明规则)。
Short answer: "Yes" with an "If," long answer: "No" with a "But."
These days I tend to miss controller-level unit tests in favour of strong unit-test coverage of models and business objects and functional-test coverage with Cucumber. The assumption here is that the controllers are very light-weight objects routing data into underlying models that encapsulate the vast majority of business logic.
However, I still do tend to have some very light coverage of some of the control flow at the controller level. It just tends to be more of a sanity-check.
One of the issues with controller-level testing is that you often either have to mock or generate a large number of models and objects in order to test effectively. Given this, I find it more valuable to push these tests up into the functional layers where the style of testing allows you to more efficiently express these dependencies (either by explicitly following the steps required to generate them through your application itself or through a system like Cucumber's declarative rules).
一切都值得进行单元测试。在这种情况下,这取决于控制器中实现了多少逻辑...在小型项目中,您可以没有附加外部逻辑,并且您可能希望在控制器中进行一些数据库操作(就像许多 Microsoft 示例一样) 。在更大的解决方案中,您可能不需要测试控制器,因为它的工作只是调用指定的业务逻辑方法......这不是关于控制器是否值得进行单元测试,而是关于它们包含的代码是否值得...... 。
Everything is worth to be unit tested. In this case it depends on how much of the logic is realized in the controllers... In small project you can have no external logic attached and you may want to make some of the database operations in your controller (like on many Microsoft examples). In bigger solutions you may not need to test the controller as far as it's job is just to invoke specified business logic methods... It's not about if controllers are worth to be unit tested, it's about if the code that they contains is...
MVC 模式的最佳功能之一是可以独立于视图的 HTML 输出来测试控制器。将逻辑与 HTML 输出混合在一起的页面很难测试,这是 MVC 解决的问题之一 - 它使您的控制器完全关于逻辑,并且您可以在根本不解析 HTML 的情况下测试它。
理想情况下,您的控制器将从单独的数据访问类获取数据,您可以将其存根用于测试,因此您只是测试逻辑。本质上,您可以将控制器与数据库隔离,就像 MVC 将控制器与视图隔离一样 - 然后测试就很容易,因为您也不需要包含测试数据的数据库。
One of the best features of the MVC pattern is that the controllers can be tested in isolation of the HTML output by the views. Pages that mix the logic with the HTML output are hard to test, and this is one of the problems that MVC solves - it makes your controller all about logic and you can test it without parsing HTML at all.
Ideally, your controller will get data from separate data access classes, which you can stub out for your tests, so you are just testing the logic. Essentially you isolate your controller from the database in the same way MVC isolates it from the view - then the tests are easy because you don't need a database with test data either.