>Octokit 响应的类型为 Sawyer::Response
它们看起来像这样:
{:name=>"code.py",
:content => "some content"}
我试图像这样存根我的请求
reponse_body = {:content => "some content"}
stub_request(:any, /.*api.github.com/repos/my_repo/(.*)/code.py/).to_return(:status => 200, :body => response_body)
在我的代码中,然后调用 response.content,因此我希望能够从响应中获取内容。
我目前收到错误:"WebMock::Response::InvalidBody:必须是以下之一:[Proc,IO,Pathname,String,Array]。"哈希"给定"。 response_body的正确格式是什么? 如果我把它变成一个json,那么我就不能在我的代码中对对象执行response.content。
您正在传递哈希作为预期的响应,而 Webmock 不知道应该将其编码为什么(请参阅此 Webmock 问题)。正如您提到的,您可以使用 response_body.to_json
,但是您将无法使用点表示法来访问数据。
由于您使用的是 RSpec,因此我会使用 Test Doubles 来假装您有一个Sawyer::Resource
对象:
response_body =
[
double("Sawyer::Resource",
{
:name=>"code.py",
:content => "some content"
})
]
然后,您应该能够像使用实际响应一样使用点表示法访问数据。
您需要以字符串形式提供 JSON 正文和适当的内容类型标头。 例如,存根调用
Octokit::Client.new.user(user_login)
你需要类似的东西
stub_request(:get, "https://api.github.com/users/#{user_login}")
.to_return(
status: 200,
body: user_json, # a string containing the JSON data
headers: { content_type: 'application/json; charset=utf-8' }
)
(如果您不提供 Content-Type 标头,Octokit 将不会尝试解析 JSON,您只会返回原始字符串。
如果你看一下Octokit源代码,你可以看到他们在自己的测试中使用Webmock。(该测试中调用的json_response()
方法在 helper.rb
中。
我遇到了这个确切的问题,最后通过删除 Octokit 客户端解决了它。为了检查Octokit中的测试覆盖率,我按照此处的说明进行操作。
Octokit 请求都使用 VCR 进行测试,因此假设您对它们的测试覆盖率感到满意,那么在您的应用程序中存根 Octokit::Client 是相当安全的。
如果有人仍然感到困惑,这里有一个完整的示例,如何使用 rspec 测试 Octokit 调用。
方法:
require 'octokit'
def get_user_name(login)
Octokit.configure { |c| c.api_endpoint = 'https://git.my_company.com/api/v3/' }
client = Octokit::Client.new(:access_token => 'my_token')
response = client.user(login)
return response.name
end
测试:
describe '#get_user_name' do
it 'should return name' do
response_body = {:name => "James Bond"}
stub_request(:get, "https://git.my_company.com/api/v3/users/bondj").
to_return(status: 200,
body: JSON.generate(response_body),
headers: { content_type: 'application/json; charset=utf-8' })
result = subject.send(:get_user_name, 'bondj')
expect(result).to eq('James Bond')
end
end