比方 Spork,人们疏于在Rail开发应用中去驾驭规范的一个基本的原因是运行的规范套件所需要的时间。很多工具可以用来缓和这个麻烦。 Zeu和 Spring事实上,Rail4.1将会在春季推出规范。倒霉的这些工具仅仅是解决问题症状的一个拐杖,而不是解决问题自身。实际的问题是书写耦合度高的代码需要有一个完整的Rail架构支撑,这个架构会缓慢启动。
开发解耦代码,就是写SOLIDRail代码。举一个特殊的例子,一种解决方法是书写的代码是独立的元件尽可能的与系统分离。用另外的话说。可以直接写一个类模块去创建一个事例。而不是使用依赖的拔出的方法去去除涉及到类的硬编码。仅仅需要去保证:平安的采用模块符号或者懒惰的评价去得到默认的引用。以下是一个服务,需要在ActiveRecord模块中创建一个小工具。采用懒惰的评价去介入的方法来替换直接的引用工具类。这可以解耦我代码,同时不需要ActiveRecord载入。
可以开始重新组织怎么建立自己的规范和最小化环境需求来运行这些规范和满足规则需求的代码。典型spec_helper.rb会有一个如下的一行代码:#Atightlicouplclass.Wedon'twantthis. classMyService defcreate_widgetparam Widget.crparam endend #Wecaninjectintheinitializer classMyService attr_read:widget_factory definitidependencies={} @widget_factori=dependencies.fetch:widget_factori{Widget} end defcreate_widgetparam widget_factory.crparam endend #Orwecanexplictliinjectviaasetterwithalazireader classMyService attr_writ:widget_factory defwidget_factory @widget_factori||=Widget end defcreate_widgetparam widget_factory.crparam endend #Aspecifinjectthedependusthesecondmethod describMyServicdo subject:servic{MyService.new} let:widget_factori{doubl'widget_factory',create:nil} befor{service.widget_factori=widget_factori} it'creatawidgetwiththefactory'do service.create_widget{name:'sprocket'} expectwidget_factori.tohave_receiv:creat.with{name:'sprocket'} endend当你采用这种方式写代码时。
可以使用一个不含有上面那行代码的配置文件。那么让我开始创建一个轻量级的rb包:base_sepc_helper.rbrequirFile.expand_path"../../config/environment",__FILE__ 这个将会载入整个的Rail顺序且降低测试运行速度。为了让规范达到更快的速度。:
实际上并没有导入所有的Rail相当的轻量级并且方便性超过了损耗。每个需要这个base包的helper里,将会添加我顺序相对应的局部到ActiveSupport::Dependencies.autoload_path中。ENV["RA ILS_ENV"]||='test'requir'rubygems' RA ILS_ROOT=File.expand_path'../..',__FILE__ Dir[File.joinRA ILS_ROOT,'spec/support/**/*.rb'].each{|f|requirf} RSpec.configurdo|config| config.mock_with:rspec config.ord='random' #Yourpreferconfigoptiongohere end requir'active_support'requir'active_support/dependencies'通过请求active_support和active_support/depend包来访问Rail使用的自动装载机。
简单的Rubi对象说明
可以在任意一个上下文中创建一个你所需要的辅助细则。例如,取决于你指定的应用顺序局部。最简单的指定一个任意类型的Rubi纯类作为服务类。如下面services_spec_helper.rb例子
"spec/support_services/**/*.rb"].each{|f|requirf} ActiveSupport::Dependencies.autoload_path<<"#{RA ILS_ROOT}/app/services"装饰说明requir'base_spec_helper'Dir[File.joinRA ILS_ROOT.
可能会选择布商,于你装饰而言decorators_spec_helper.rb就如以下所看到
"spec/support_decorators/**/*.rb"].each{|f|requirf} ActiveSupport::Dependencies.autoload_path<<"#{RA ILS_ROOT}/app/decorators"模块规范requir'base_spec_helper'requir'draper'Draper::ViewContext.test_strategi:fastDir[File.joinRA ILS_ROOT.
而且并不会真的创建对象.实际上,测试模块还需要做一点事情.假设你现在正在用ActiveRecord会需要建立一个和数据库的连接.并不需要将defactory_girl或者database_clean加入你测试中。唯一需要进行创建数据库对象的地方就是当你进行特定对象测试的时候.当你确实需要创建一些对象的时候,只需要手动的进行清理和转换.这就是一个样例models_spec_helper.rb:
"spec/support_models/**/*.rb"].each{|f|requirf} #Manualconnecttothedatabase ActiveRecord::Base.establish_connect YA ML.loadFile.readRA ILS_ROOT+'/config/database.yml'['test'] ActiveSupport::Dependencies.autoload_path<<"#{RA ILS_ROOT}/app/models"特点说明requir'base_spec_helper'requir'active_record'#RSpechasomenicematcherformodelsowe'llpullthemin requir'rspec/rails/extensions/active_record/base'Dir[File.joinRA ILS_ROOT.
当我创建特色应用时,最后.会需要Rail全套知识并且feature_spec_helper.rb看起来就和spec_helper.rb差不多了.