【问题标题】:rspec block return valuerspec 块返回值
【发布时间】:2018-04-19 18:37:10
【问题描述】:

我有一个与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 作为块的最后一行,它会返回模拟,但我需要测试的代码不会这样做。而且我无法让公司中的每个人都修改这种特定的代码样式,以便更轻松地编写我的测试。

有什么聪明的主意吗?

【问题讨论】:

  • 如果你期望返回值响应body,为什么你有方法返回post_response.body?除非我错过了什么。
  • 我认为你遗漏了一些东西。 Faraday.post 块返回一个响应 :body 的对象。我不是说方法的返回值也必须响应:body
  • 像其他东西一样存根? Faraday.should_receive(:post).and_yield(request).and_return(something_that_responds_to_body)
  • @engineersmnky 啊,太明显了!是的,这行得通。老实说,我从来没有想过我可以将and_return()and_yield 联系起来。感谢您的回复...当系统允许时,我会在这里回答我自己的问题。

标签: ruby rspec faraday


【解决方案1】:

答案既简单又明显。

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_returnand_yield 链接起来,以确保该块返回特定的内容。感谢@engineersmnky 的指点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2021-02-21
    • 2011-08-21
    • 1970-01-01
    相关资源
    最近更新 更多