美文网首页
rspec(4) - request

rspec(4) - request

作者: auguszou | 来源:发表于2017-05-17 21:30 被阅读0次

    没有测试的代码就是耍流氓

    1. rspec(1) - summary
    2. specs(2) - model
    3. specs(3) - controller
    4. specs(4) - request
    5. specs(5) - mock
    6. [specs(6) - mailer]
    7. [specs(7) - view]
    8. [specs(8) - routing]
    9. [specs(9) - helper]
    10. [specs(10) - factory-girl]
    11. [specs(11) - fake other gems]
    12. [specs(12) - sidekiq]
    13. [specs(13) - db migration]
    14. [specs(14) - timecop]
    15. [specs(15) - jenkins]

    in general, we want to test our api, what should we do in rspec?

    require "rails_helper"
    
    RSpec.describe "User management", :type => :request do
    
      it "creates a User" do
        headers = {
          "ACCEPT" => "application/json",     # This is what Rails 4 accepts
          "HTTP_ACCEPT" => "application/json" # This is what Rails 3 accepts
        }
        lamda do
          post "/users", { user: {name: "zql"} }, headers
        end.should change(User, :count).by(1)
    
        expect(response.content_type).to eq("application/json")
        expect(response).to have_http_status(:created)
    
        user = User.last
        user.name.should eq "zql"
        # or 
        expect(user.name).to eq "zql"
      end
    
    end
    

    webmock

    what should we do if we want to test external request?
    a nice gem you can use, webmock
    just like this(examples from webmock github):

    stub_request(:post, "www.example.com").
      with(body: "abc", headers: { 'Content-Length' => 3 })
    RestClient.post('www.example.com', "data[a]=1&data[b]=five",
      content_type: 'application/x-www-form-urlencoded')    # ===> Success
    
    RestClient.post('www.example.com', '{"data":{"a":"1","b":"five"}}',
      content_type: 'application/json')    # ===> Success
    
    RestClient.post('www.example.com', '<data a="1" b="five" />',
      content_type: 'application/xml')    # ===> Success
    

    it's so easy to do this, right?

    and more.

    • match body
    stub_request(:post, "www.example.com").
      with(body: hash_including({data: {a: '1', b: 'five'}}))
    
    RestClient.post('www.example.com', "data[a]=1&data[b]=five&x=1",
    :content_type => 'application/x-www-form-urlencoded')    # ===> Success
    
    • match headers
    stub_request(:any, "www.example.com").
      with(headers:{ 'Header-Name' => 'Header-Value' })
    
    uri = URI.parse('http://www.example.com/')
    req = Net::HTTP::Post.new(uri.path)
    req['Header-Name'] = 'Header-Value'
    
    res = Net::HTTP.start(uri.host, uri.port) do |http|
      http.request(req, 'abc')
    end    # ===> Success
    
    • auth required
    stub_request(:get, "www.example.com").with(basic_auth: ['user', 'pass'])
    # or
    # stub_request(:get, "www.example.com").
    #   with(headers: {'Authorization' => "Basic #{ Base64.strict_encode64('user:pass').chomp}"})
    
    Net::HTTP.start('www.example.com') do |http|
      req = Net::HTTP::Get.new('/')
      req.basic_auth 'user', 'pass'
      http.request(req)
    end    # ===> Success
    

    please visit webmock if you wnat to more advange usage

    but if we use gems like faraday or rest-client, so what should we should in rspec?
    yeah, we want to mock a api request like mocking a model. here we go.

    faraday

    firstly, you should have a look at faraday testing, here are some example provided:

    conn = Faraday::Adapter::Test::Stubs.new do |stub|
         stub.get('/ping') { |env| [200, {}, 'hello world!'] }
         stub.get('/other_url') { |env| [ 200, {}, 'hello, it's me, another test case' ]}
    end
    # or
    cnnn = Faraday.new do |builder|
      builder.adapter :test, stubs do |stub|
        stub.get('/test') { |env| [ 200, {}, 'test case' ]}
      end
    end
    

    test request result

    resp = test.get '/ping'
    resp.status.should eq 200
    resp.body.should eq 'hello world!'
    
    resp = test.get '/other_url'
    resp.status.should eq 200
    resp.body.should eq 'hello, it's me, another test case'
    

    file upload test

    conn = Faraday.new('http://localhost') do |http|
      http.request :multipart
      http.request :url_encoded
      http.adapter :test, stubs do |stub|
         stub.post('/upload') { |env| [ 200, {}, {success: true, message: "upload successfully!"} ] }
      end
    end
    
    payload = { :file => Faraday::UploadIO.new('~/test.jpg', 'image/jpeg') }
    resp = conn.post('/upload', payload)
    resp.status.should eq 200
    data = JSON.parse(resp.body)
    data["success"].should eq true
    data["message"].should eq "upload_successfully!"
    

    rest-client

    oh, you willl find this gem's test based on webmock.
    it looks like this.

    stub_request(:get, "www.example.com").to_return(:body => body, :status => 200)
        response = RestClient.get "www.example.com"
        expect(response.code).to eq 200
    expect(response.body).to eq body
    

    just do it as webmock.

    done!

    相关文章

      网友评论

          本文标题:rspec(4) - request

          本文链接:https://www.haomeiwen.com/subject/kpljxxtx.html