【问题标题】:Stubbing with Faraday and Rspec使用 Faraday 和 Rspec 存根
【发布时间】:2012-12-29 01:28:16
【问题描述】:

我有一个看起来像这样的模型:

class Gist
    def self.create(options)
    post_response = Faraday.post do |request|
      request.url 'https://api.github.com/gists'
      request.headers['Authorization'] = "Basic " + Base64.encode64("#{GITHUB_USERNAME}:#{GITHUB_PASSWORD}")
      request.body = options.to_json
    end
  end
end

还有一个如下所示的测试:

require 'spec_helper'

describe Gist do
  context '.create' do
    it 'POSTs a new Gist to the user\'s account' do
      Faraday.should_receive(:post)
      Gist.create({:public => 'true',
                   :description => 'a test gist',
                   'files' => {'test_file.rb' => 'puts "hello world!"'}})
    end
  end
end

不过,这个测试并不能真正让我满意,因为我正在测试的是我正在使用 Faraday 进行一些 POST,但我实际上无法测试 URL、标题或正文,因为它们是用块传入。我尝试使用 Faraday 测试适配器,但我也没有看到任何测试 URL、标头或正文的方法。

有没有更好的方法来编写我的 Rspec 存根?或者我是否能够以某种我无法理解的方式使用法拉第测试适配器?

谢谢!

【问题讨论】:

    标签: rspec mocking stubbing faraday


    【解决方案1】:

    我的朋友@n1kh1l 向我指出了and_yield Rspec 方法和this SO post,它们让我可以这样编写测试:

    require 'spec_helper'
    
    describe Gist do
      context '.create' do
        it 'POSTs a new Gist to the user\'s account' do
          gist = {:public => 'true',
                  :description => 'a test gist',
                  :files => {'test_file.rb' => {:content => 'puts "hello world!"'}}}
    
          request = double
          request.should_receive(:url).with('https://api.github.com/gists')
          headers = double
          headers.should_receive(:[]=).with('Authorization', "Basic " + Base64.encode64("#{GITHUB_USERNAME}:#{GITHUB_PASSWORD}"))
          request.should_receive(:headers).and_return(headers)
          request.should_receive(:body=).with(gist.to_json)
          Faraday.should_receive(:post).and_yield(request)
    
          Gist.create(gist)
        end
      end
    end
    

    【讨论】:

      【解决方案2】:

      您可以使用出色的 WebMock 库来存根请求并测试已发出请求的预期,see the docs

      在您的代码中:

      Faraday.post do |req|
        req.body = "hello world"
        req.url = "http://example.com/"
      end
      
      Faraday.get do |req|
        req.url = "http://example.com/"
        req.params['a'] = 1
        req.params['b'] = 2
      end
      

      在 RSpec 文件中:

      stub = stub_request(:post, "example.com")
        .with(body: "hello world", status: 200)
        .to_return(body: "a response to post")
      expect(stub).to have_been_requested
      
      expect(
        a_request(:get, "example.com")
          .with(query: { a: 1, b: 2 })
      ).to have_been_made.once
      

      【讨论】:

        【解决方案3】:

        我的解决方案:

        stub_request(method, url).with(
          headers: { 'Authorization' => /Basic */ }
        ).to_return(
          status: status, body: 'stubbed response', headers: {}
        )
        

        使用 gem webmock

        您可以通过替换来加强验证:

        /Basic */ -> "Basic #{your_token}"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-16
          相关资源
          最近更新 更多