我遇到的问题与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
作为块的最后一行,它将返回模拟,但我需要测试的代码不会这样做。我不能让公司里的每个人都修改这种特殊的代码风格,以便更容易编写我的测试。
任何聪明的想法?
答案 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指针。