与法拉第和Rspec的碰撞

与法拉第和Rspec的碰撞,rspec,mocking,stubbing,faraday,Rspec,Mocking,Stubbing,Faraday,我有一个这样的模型: 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_PASSWOR

我有一个这样的模型:

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
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
下面是一个测试:

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
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
不过,这个测试并不能真正让我满意,因为我测试的只是我在用法拉第发一些帖子,但我不能真正测试URL、标题或正文,因为它们是通过一个块传入的。我尝试使用法拉第测试适配器,但我也看不到用它来测试URL、标题或正文的任何方法

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


谢谢

我的朋友@n1kh1l向我指出了
和_yield
Rspec方法,让我这样编写测试:

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
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

您可以使用优秀的WebMock库来存根请求,并测试已发出请求的期望值

在代码中:

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
我的解决方案:

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

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

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