第一部分包括,介绍,配置并建立应用,基本业务逻辑与测试
介绍:众所周知 Rails 最初是为了迅速构建 Web 应用而建立的框架,但是技术总是会随着发展而变化,移动端的应用不需要很多富文本信息,作为服务端只要提供纯粹的JSON API就够了。所以去年Rails5发行以来,rails-api(https://github.com/rails-api/rails-api) 这个gem被整合到 Rails 内核中。对比于同样使用 Rails 建立的普通的 Web App,他们的区别是:
-
应用的中间件(middleware)减少了
-
ApplicationController 继承自 ActionController::API,而不是 ActionController::Base
-
不需要建立的对应的视图文件,不需要HTML,CSS,嵌入式Ruby什么的那一堆东西
接下去,我们来建立这个应用,检查下环境:
整理下,我们需要的RESTful API,给自己一个小目标😊
好的,开始建立应用
–api 是说明应用只是支持JSON API,那些 Web 应用的中间件我们不要。-T 是说,我们不要 Rails 自带的测试框架 Minitest,因为我们要测试 Request,还有他的返回值,RSpec 是首选。看下我们需要的 gem,并给出 list:
rspec-rails – 测试框架
factory_girl_rails – 替代fixtures,语法更加直接
shoulda_matchers - 提供 RSpec 额外的 matchers
database_cleaner – 你说呢
faker – 假数据,测试用的
这是最后的Gemfile:
完了 bundle install,我们在本地使用 sqlite3 数据库,但是 heroku 不支持,换成了 Postgres。接下来我们配置下 Rspec
你会发现增加了以下三个文件:.rspec, spec/spec_helper.rb, spec/rails_helper.rb
再增加一个factories目录:
然后我们配置这些添加的Gem, 打开spec/rails_helper.rb
现在创建Models,开始书写基本的业务内容
Model 的名字叫 Todo, 有两个属性 title, created_by, 顺便检查下生成的迁移文件,db/migrate/[timestamp]_create_todos.rb
同样的,我们增加另外一个 Model 叫做 Item
reference 是添加外键,一个 item 点开来以后是多个 todo 待办事项对吧,所以他们的关系也是1:n。打开迁移文件,确认外键关系
最后记得,把model映射到数据库,Rails 有专业术语叫 migrate
好吧,测试驱动,我们要开始写测试了,看到 spec/models/todo_spec.rb
其实我不加注释,也应该能看懂,因为太显而易见了😄。不得不说,Rspec 是非常具有表现力的 DSL(Domain Specific Language)。继续看到 spec/models/item_spec.rb
看到 shoulda matchers 在 Rspec中的作用了对吧,字面意思就是 item 应该属于 todo,验证 name 字段的存在性,就是普通的英语短句
如果现在运行测试用例,当然不可能通过,不信自己试下:
都是红的,然后我们一步步让他变绿,看到 app/models/todo.rb
app/models/item.rb
再次运行spec,都变绿了对吧,必须的嘛。现在来写 Controller
我们不会写 controller 的测试,而是要写 request 的测试,因为覆盖得更加多,包括路径,请求完成以后的回调。创建文件夹和相关的文件
记得不能写成 todos_spec.rb,会引起重复引用的错误:in `method_missing’: Factory already registered: item (FactoryGirl::DuplicateDefinitionError)
增加固件测试,就是跑测试用例时候的样本文件:
编辑文件spec/factories/todos.rb,加上两个假数据
再看 spec/factories/items.rb,类似的,先不管外键
最后写关键的 Request 测试部分,看到 spec/requests/todos_spec.rb
一个 describe 对应一个 Request 测试,各种断言,一次返回10条 todos,json 数据不能为空,而且状态码是200,太明显了对吧,Rspec确实语法简练。然后我们要定义 json 方法,解析 JSON 数据到 Ruby hash,创建
写入spec/support/request_spec_helper
support 目录不是自动添加到工程的,打开这个文件 spec/rails_helper.rb 写入
然后我们配置跳转的路由,打开config/routes.rb
对,就是这么神奇,一个循环😄
看下路由对不对,然后配置 controller 中的方法,app/controllers/todos_controller.rb
还记得那个返回状态码的 json_response 方法,配置下,app/controllers/concerns/response.rb
还有统一的异常处理,app/controllers/concerns/exception_handler.rb
在 TodosController 中我们使用 create!,而不是 create 方法,这样就直接抛出异常 ActiveRecord::RecordInvalid,在 ExceptionHandler 中实现异常的复用。然后在 app/controllers/application_controller.rb 加入帮助文件,让他们生效
最后测试下,正常情况下都是绿的
接下去类似的写下item的测试,app/requests/items_spec.rb
编辑 app/controllers/items_controller.rb
所有测试都变绿通过