如何为 webmock 存根正确复制 Octokit 请求响应的响应主体

Posted

技术标签:

【中文标题】如何为 webmock 存根正确复制 Octokit 请求响应的响应主体【英文标题】:How to correctly replicate response body of an Octokit requests' response for webmock stub 【发布时间】:2016-10-03 22:58:21 【问题描述】:

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。

【问题讨论】:

【参考方案1】:

您正在传递一个哈希作为预期响应,而 Webmock 不知道应该将其编码为什么 (see this Webmock issue)。正如您所提到的,您可以使用response_body.to_json,但是您将无法使用点符号来访问数据。

由于您使用的是 RSpec,我会使用 Test Doubles 来假装您有一个 Sawyer::Resource 对象:

response_body = 
  [
    double("Sawyer::Resource",
      
        :name=>"code.py",
        :content => "some content"
      )
  ]

然后,您应该能够像使用实际响应一样使用点符号访问数据。

【讨论】:

好主意,我也是这么想的,但是在双重上得到同样的错误。 WebMock::Response::InvalidBody: must be one of: [Proc, IO, Pathname, String, Array].'RSpec::Mocks::Double' given 啊!我打错了。 response_body 应该是一个包含一个元素的数组。该元素将成为测试替身。我会更新我的答案。 这一切都很好,并且可以工作,但是现在测试中的代码我们收到了一个数组,而它通常会收到一个哈希值。事实上,如果哈希在数组中返回,则不需要 double,因为这是允许的返回类型。【参考方案2】:

我遇到了这个确切的问题,最后通过删除 Octokit 客户端解决了这个问题。为了检查 Octokit 中的测试覆盖率,我按照说明 here。

Octokit 请求都使用VCR 进行测试,因此假设您对它们的测试覆盖率感到满意,在您的应用程序中存根 Octokit::Client 是相当安全的。

【讨论】:

【参考方案3】:

您需要以字符串形式提供 JSON 正文,以及适当的 Content-Type 标头。例如,存根调用

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 source,您可以看到他们如何在自己的测试中使用 Webmock。 (该测试中调用的json_response() 方法在helper.rb 中。)

【讨论】:

我缺少的是响应标头,谢谢!

以上是关于如何为 webmock 存根正确复制 Octokit 请求响应的响应主体的主要内容,如果未能解决你的问题,请参考以下文章

存根谷歌地方调用 selenium v​​s capybara-webkit

为孩子提供属性时如何为 React.cloneElement 分配正确的类型?

您如何为用于 jquery 编码的菜单栏正确编写 CSS 代码?

如何为需要 4 个数字输入的 C 程序编写 Bash 脚本? [复制]

如何为 SwiftUI 动态构建视图并呈现它?

如何为开发目的禁用 Spring Cloud Stream 绑定?