Rails模式的实际应用--第二部分:Views
在此系列博文中,我们会一步步亲身实践如何改变Rails应用的默认设计使其变得更加责任清晰并且容易测试。
别忘了其他的部分的内容哦!
Rails模式的实际应用--第三部分:Controllers
你可以参考GitHub上的知识库,里面包含了我们讨论的所有的代码。
Ruby的.erb模板是Rail默认的Views。从技术上来说它们是Ruby与HTML的混合。这在提供很多灵活的同时,也会导致视图里的大量逻辑。
缺点就是我们放越多的逻辑在视图里面,测试这些逻辑就会变得越发的困难。尽管有Capybara和Selenium一类的工具可以给我们帮助。在某些场景下用这些方法是可以的,但是不应该被作为第一选择,因为这些测试方法是缓慢且脆弱的。前端测试通常包括渲染UI,这大大的增加了测试套件的执行时间。除此之外,一旦这些发生改变,依赖于类名甚至网站链接的测试很有可能就会执行失败。
因此,从通用测试的角度,我们应该尽量不去通过UI来测试我们的应用。有时这也称为“submarine testing”,这个测试开始于UI层之后,即应用表面之下的一层。
这使得我们不得不尽可能的让views保持简洁。我们放越多的逻辑在里面,就有越多的逻辑我们不能用这种方法来测试。
一个方案就是引入views里的presenters.理想情况下,一个视图只调用那个presenters里的方法并且尽可能少的带入逻辑。像说过的那样,结束并不容易,很多时候也并不需要。例如在一个视图里,包含一些像下面的代码一样的东西是可以的:

只要presenter里的logged_in?有合适的单元测试。在一个视图里有这类的逻辑大多数时候是可以的,因为它仍然可以以一种足够简单的方法来测试,即使可能是手工测试。
介绍Movies
继续Movie的例子,让我们来看看一个movie是如何显示的。

使得测试通过是相对简单的。Controller从数据库查找一个movie并以一个实例变量的形式把它提供给Views。

然后视图会格式化movie的数据。
这里有什么可以提升的东西吗? 
问题在于view里面的逻辑。更准确的说,对titlelize和strftime的调用包含域逻辑,应该单独测试。但是又因为是直接写在view里面的,测试起来便没有正常情况那么容易了。
添加一个Movie Presenter
在一个presenter里面,格式化一个movie数据的逻辑是进行覆盖。让我们以测试一个标题作为开始。

为了使得测试通过,我们把view里面已经存在的代码挪到新的MoviePresenter里面。

以同样的方式,我们可以为release_date也添加一个测试。

使得测试通过,就像把代码从view里面挪到presenter一样简单。我们在做这个的时候,可以顺便修正一个bug,原始的格式里面,字符串“%e”会在日期之前增加一个空格。我们真正想要的只是一个月里的某一天,没有多余的空格也没有0(也就是,“%-d”)。

Presenter应该能够展示一个Movie里面的所有数据,那么我们来为我们的描述增加最后一个测试。

未完,待续~
【英文原文:https://8thlight.com/blog/christoph-gockel/2016/10/26/getting-rails-on-track-part-2-views.html】
{测试窝原创译文,译者:周婷婷}
译者简介:周婷婷,专注于云计算、自动化、网络运维领域的工作者。