第7章使用请求测试-测试API . Rspec: everyday-rspec实操。

测试应用与非人类用户的交互,涵盖外部 API 

 

7.1request test  vs feature test 

 

RSpec 来说,这种专门针 对 API 的测试最好放在 spec/requests 目录中,与前面编写的功能测试分开。

这种测试也不使用 Capy- bara,因为它模拟的是浏览器交互,而不是程序交互。

我们要使用的是前面测试控制器响应的 HTTP 动 词:getpostdelete patch。 

end-point:端点。 

 

7.2测试GET请求 

 向API请求数据。

请求测试与控制器测试不通的地方在于,可以使用应用的任何路由。

bin/rails g rspec:request projects_api 

create  spec/requests/projects_apis_spec.rb 

 

    it "loads a project" do
      user = FactoryGirl.create(:user)
      FactoryGirl.create(:project, name:"Sample Project")
      FactoryGirl.create(:project, name:"Second Sample Project", owner: user)
#发送HTTP GET请求,为了验证身份, API 要求提供用户的电子邮件地址和验证令牌,因此我们将其放到参数中 
      get api_projects_path, params:{
        user_email: user.email,
        user_token: user.authentication_token
      }
      expect(response).to have_http_status(:success)

#调试:看看response.body是什么。一个array,包含了登陆用户的projects的信息.

[{"id":2,"name":"Second Sample Project","description":"A test project.","due_on":"2018-05-26","created_at":"2018-05-19T07:30:14.169Z","updated_at":"2018-05-19T07:30:14.169Z","user_id":1}] 

      byebug  
      puts "---#{response.body}---"
      json = JSON.parse(response.body)
      puts "---#{json}---" 
      byebug

#调试:转化为json ,: 变为 =>

[{"id"=>2, "name"=>"Second Sample Project", "description"=>"A test project.", "due_on"=>"2018-05-26", "created_at"=>"2018-05-19T07:30:14.169Z", "updated_at"=>"2018-05-19T07:30:14.169Z", "user_id"=>1}] 

      expect(json.length).to eq 1
      project_id = json[0]["id"]
      puts "---#{project_id}---"
      byebug
# 期望json的数据是一条,之后获取这个project的🆔。用于再次请求API,获得这个project的详细信息。
      get api_project_path(project_id), params:{
        user_email: user.email,
        user_token: user.authentication_token
      }
      expect(response).to have_http_status(:success)
      json = JSON.parse(response.body)
      expect(json['name']).to eq "Second Sample Project"

#最后,解析第二次请求返回的JSON数据。看看是否match. 

    end

 

JSON.parse()方法 

一般从web上response的数据格式是string,这个数据又是用JSON模式写的,则可以使用parse(). 

Parsse the data with JSON.parse(), and the adta becomes a JavaScript object. 

 

7.3 测试POST 请求 

向API发送POST请求。

    it "creates a project" do
      user = FactoryGirl.create(:user)
      project_attributes = FactoryGirl.attributes_for(:project)
      puts "~~~#{project_attributes}~~~"
      byebug
#得到一个成功创建项目的属性散列

{:name=>"Project 1", :description=>"A test project.", :due_on=>Sat, 26 May 2018 08:22:01 UTC +00:00} 

#向API发送POST请求。需要传递身份验证,项目相关属性。

      expect{
        post api_projects_path, params:{
          user_email: user.email,
          user_token: user.authentication_token,
          project: project_attributes
        }
      }.to change(user.projects, :count).by(1)
# response:#<ActionDispatch::TestResponse:0x00007fadc95a6990>

# response.body: {"status":"created"}

# response.header: 

 

# {"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "Content-Type"=>"application/json; charset=utf-8", "ETag"=>"W/\"5c15461069e69109955c72671ffc465d\"", "Cache-Control"=>"max-age=0, private, must-revalidate", "Set-Cookie"=>"_projects_session=V056Ym11dkpTMzI3Qnl1ell4MVJCY3NacWZTNUIyMEFPd1p3dENyTzBHT05nek1OcTBZeFhzVHMyUWY0aUtjaytJaVBVSGVkdGl5THNGcGEzTVcrcDhJNDNUMEN4c0JwVml1a2dibU1XeUFoVVZHSnRjRzExUUh4TGp3aUxxdWwvaVFvVGtjK3RkRHdIVTdiZXVCTGRnPT0tLTZOY0hWOWwvOHY0aDJnb0t5amtCYVE9PQ%3D%3D--a5331d1bfca86dd6979192edece7a50a4d2cf6c5; path=/; HttpOnly", "X-Request-Id"=>"2629be13-6804-4c45-b88a-0051b4be16ae", "X-Runtime"=>"0.012613", "Content-Length"=>"20"}
      expect(response).to have_http_status(200)
    end
  end

 

 

7.4 把控制器测试替换为请求测试

 

要点:把控制器测试中的HTTP VERB 后的:create等方法改为相对路径

post :create改为post projects_path

 

另外:

 

API 的控制器不同,这些控制器动作使用标准的电子邮件和密码验证身份 

1.创建spec/support/request_spec_helper.rb,
module RequestSpecHelper

2.然后,在spec/rails_helper.rb文件中让Devise把辅助方法应用到请求测试中。

RSpec.configure do |config|

... 

  config.include Devise::Test::ControllerHelpers, type: :controller

  config.include RequestSpecHelper, type: :request

end 

 

7.5 小结

 redirect_to 可以用在请求测试,

 have_http_status 可以用在feature,request 人, controller测试。

具体见https://www.rubydoc.info/gems/rspec-rails/frames#redirect_to 

 

posted @ 2018-05-19 15:45  Mr-chen  阅读(469)  评论(0编辑  收藏  举报