其实这个观点我已经在“单元测试中的“单元‘如何定义?”中谈及,大概标题比较极端,吸引不少人兴趣,我再有逻辑的分析一下。
首先,我们必须有一个共认的上下文前提,这个前提应该是Bob大叔的“干净的架构”,图如下所示:

外圈依赖内圈,内圈不可依赖外圈,内圈代表业务,外圈代表技术架构。内圈核心业务实体应该不依赖外圈的UI或数据库。
Bob大叔将MVC模式中控制器Controller归于次外圈,而一般对业务实体和用例的单元测试也是和控制器Controller同处一个次外圈中,这里就造成了一个混淆,很多人在MVC控制器中实现对业务用例的单元测试,单元测试是TDD主张的测试优先的做法,而Ruby的MVC框架Rails创建者DHH就非常反对这种做法,认为这两者混淆在一起,破坏了MVC设计原本对控制器的定义。
问题根源我认为其实只是将处于同一个层次的两种目的的功能混合在一起了。
下面的问题是,为什么这两者容易混淆在一起?是不是可能MVC过于强势或死板呢?我个人很早注意到这个问题,所以,提出MVC模式已死,建议以DCI等架构,当然包括后来的DDD/CQRS来替代,这也是符合2012年Bob大叔提出的干净架构的目标。从今天观点来看,这样才能真正避免MVC模式和单元测试的冲突。
作为Ruby的MVC框架Rails创建者DHH之所以提出TDD已死,其中一个原因可能是他已经深刻感受到MVC与TDD的矛盾之处,这种矛盾如同对象和关系数据库,已经到了水火不容,不可调和地步,也许只有宣布一方死亡才可保持另外一方的存在。
其实随着后端RESTful架构和微服务的兴起,SpringMVC这种昔日MVC框架其实已经褪化成了REST框架,只有控制器,没有视图View,当然你可以将REST输出的JSON数据格式看成是视图View,不过这确实够牵强,JSON数据最多是视图的数据部分,如果你了解前端MVC框架AngularJS,可以明白,在AngularJS中,后端的JSON数据属于MVC的Model定义,Html的DOM才是真正视图。
在未来可能的情况下,Rails这种Ruby MVC框架也应该学习SpringMVC,顺潮流而下台阶,即使打着MVC框架名头,实际变成一个RESTful服务的控制器或处理器,该控制器已经不是协调Model和View之间的调节者(Mediator模式),而是处理前端POST/GET/DEL/PUT等动作的响应处理器Handler,在这里再实现对领域业务层的单元测试,恐怕就不会再引起别人的误会了。
从另外一个角度看,MVC模式主要是针对前端的,是向前优先的框架,而TDD单元测试是针对后端核心业务的测试,是向后优先的,就像两个人,一个人成天感慨过去(老年人),一个人经常憧憬未来(年轻人),两人在一起会有不匹配阻抗的啊。
所以,我提出“要么TDD死,要么后端MVC死”,其实只是为说明后端REST架构已经是主流现实,后端MVC框架其实已经发展到头了,MVC框架让出空间,才会有TDD单元测试生存的空间,当然如果你明白这个道理,两者共存也是可以,不过需要处理ORM框架那种超凡技巧和智慧。
本来架构很简单,搞的人多了,架构就复杂了,后端其实只要一个RESTful接口+ 业务,其他MVC框架 或ORM都是属于干净架构的次要部分,何必以次充主呢?