如何正确复制 Octokit 请求对 webmock 存根的响应的响应正文



>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

相关内容

  • 没有找到相关文章

最新更新