65.9K
CodeProject 正在变化。 阅读更多。
Home

你不应该对你的控制器进行单元测试,真的!

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (11投票s)

2013年6月16日

CPOL

3分钟阅读

viewsIcon

31079

MVC 的一个信条是它允许对你的控制器进行单元测试。但是,这并不意味着你应该这样做。在我看来,你应该把你的单元测试精力集中在更有效的领域,因为如果控制器做得对,就不需要进行单元测试。

Unit Testing MVC

单元测试本身就是一个有争议的话题,你应该对什么进行单元测试是另一个有争议的话题。这篇文章的主题源于 2010 年在 .NET London Group 会议期间的一次简短对话,我思考了一下,然后进行了更多的思考,我开始在我的项目中使用它,现在我有足够的信心分享我的想法。这是我的观点,如果你同意或不同意,请评论。

控制器应该尽可能简洁

你以前听过:“控制器不应该臃肿,控制器应该包含最少的代码”,这是一个信条。

SOLID 中的 S 代表SRP。一个控制器应该只有一个角色,它是模型和视图之间的通信层。即使有了这个角色,它也违反了 SRP,有人可能会说也许我们需要两个类来扮演控制器的角色,或者每个动作方法对应一个控制器,但我们不要深入研究这一点。

控制器,按照角色,已经承担了过多的责任,再向它添加更多的责任是一种设计上的犯罪(也许应该通过失去一些 StackOverflow 或 CodeProject 积分来惩罚 :))。

为什么控制器变得臃肿?

我之前写过关于视图如何变得臃肿的博客让臃肿的 Razor MVC 视图瘦身的三个步骤,一些要点是通用的,一些是控制器特有的

在动作方法中显式验证数据

在控制器中验证你的 viewmodel 数据违反了两个原则

  1. SRP(单一职责原则)设计原则:你正在向控制器附加更多的责任。
  2. 封装OOP(面向对象编程)原则:你将不得不将你的数据暴露在你的 viewmodel 之外,以允许另一个对象(控制器)来验证它,而对象本身应该对其自己的数据负责。

ASP.NET MVC 4 有一个很好的验证生态系统,可以帮助你将验证代码移动到它所属的位置。

将模型映射到 Viewmodel

从模型到 viewmodel 的映射不应该在动作方法中完成。我最喜欢的解决方案是使用 CQRS 类型的查询模式,这样我就不必在任何地方进行这种样板代码。这是一个很好的CQRS 入门

泄露一些业务逻辑

这不是任何业务逻辑的地方。控制器应该调用一个服务,一个典型的DDD实现,或者发出 CQRS 的查询或命令。

动作方法中的 HTTP 相关代码

在这里不应该处理需要特殊处理的特殊 HTTP 情况。Action filters 可能是答案。

你要单元测试什么?!

考虑到以上情况,如果你的动作方法几乎没有代码,那么你要单元测试什么?你想测试你是否返回了正确的视图,还是想测试你是否用正确的属性装饰了你的动作方法?我不会,我通常有一个截止日期要完成,我反对样板代码。

如果有人告诉我他们的控制器需要单元测试,我会问,你是否正确地设计了你的控制器?

结论

单元测试是一种提供更高质量软件的手段,而不是目的本身。拥有太多的冗余单元测试会导致未来的维护难题,并会花费更多的项目开发时间。

如果一个区域/层需要单元测试,那么你可能应该测试它,但对于其他区域,更多的测试可能意味着更低的质量。

更新 - 我告诉过你不要对你的控制器进行单元测试,通过保持它们为空,这里有一种保持你的控制器简洁的方法:使用 MVC 和 Document DB 实现基于 CQRS 的架构

© . All rights reserved.