rspec块返回值

时间:2018-04-19 18:37:10

标签: ruby rspec faraday

我遇到的问题与previously posted RSpec and Faraday question非常相似。为了清楚说明,我将借用其他问题的代码并做一个简单的修改,这让我感到非常悲伤。

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

    post_response.body # this is the ONLY modification!
  end
end

接受的答案适用于断言块的值,但规范将因代码post_response.body的投诉而失败。

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

确切的错误是:     故障:

1) Gist.create POSTs a new Gist to the user's account
 Failure/Error: post_response.body

 NoMethodError:
   undefined method `body' for #<String:0x007fa5f78f75d8>

我明白发生了什么。生成的rspec块返回块的最后一行的值并将其分配给post_response。与真实Faraday不同,该块不会返回响应:body的对象。

那么,如何修改测试以使块返回模拟?我知道如何更改原始代码以使其工作;我可以将request作为块的最后一行,它将返回模拟,但我需要测试的代码不会这样做。我不能让公司里的每个人都修改这种特殊的代码风格,以便更容易编写我的测试。

任何聪明的想法?

1 个答案:

答案 0 :(得分:0)

答案既简单又明显。

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).and_return(double.as_null_object)

      Gist.create(gist)
    end
  end
end

and_return链接到and_yield,以确保该块返回特定内容。感谢@engineersmnky指针。