【发布时间】: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联系起来。感谢您的回复...当系统允许时,我会在这里回答我自己的问题。