【问题标题】:wrong number of arguments in Net::HTTP requestNet::HTTP 请求中的参数数量错误
【发布时间】:2016-06-22 18:43:45
【问题描述】:

在 Sinatra 应用程序中,我正在尝试围绕 Net::HTTP 制作自己的包装器,但我被困在我的一个测试中。我正在使用 Webmock 存根请求并将其传递给Net::HTTPrequest 方法。我用 RSpec 做测试。我得到的错误是:

 Failure/Error: client.request(request)

 ArgumentError:
   wrong number of arguments (given 0, expected 1)
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/webmock-2.1.0/lib/webmock/http_lib_adapters/net_http.rb:279:in `method'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/webmock-2.1.0/lib/webmock/http_lib_adapters/net_http.rb:279:in `request_signature_from_request'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/webmock-2.1.0/lib/webmock/http_lib_adapters/net_http.rb:75:in `request'
 # ./lib/net_http.rb:19:in `request'
 # ./spec/net_http_spec.rb:21:in `block (2 levels) in <top (required)>'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:236:in `instance_exec'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:236:in `block in run'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:478:in `block in with_around_and_singleton_context_hooks'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:435:in `block in with_around_example_hooks'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:478:in `block in run'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:616:in `run_around_example_hooks_for'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:478:in `run'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:435:in `with_around_example_hooks'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:478:in `with_around_and_singleton_context_hooks'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:233:in `run'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:581:in `block in run_examples'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:577:in `map'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:577:in `run_examples'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:543:in `run'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:119:in `block (3 levels) in run_specs'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:119:in `map'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:119:in `block (2 levels) in run_specs'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1680:in `with_suite_hooks'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:118:in `block in run_specs'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/reporter.rb:77:in `report'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:117:in `run_specs'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:93:in `run'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:78:in `run'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:45:in `invoke'
 # /home/admin/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rspec-core-3.4.4/exe/rspec:4:in `<top (required)>'
 # /home/admin/.rbenv/versions/2.3.0/bin/rspec:23:in `load'
 # /home/admin/.rbenv/versions/2.3.0/bin/rspec:23:in `<main>'

net_http.rb(堆栈的第一行)的第 279 行是:

method = request.method.downcase.to_sym

在方法内部:

module WebMock
  module NetHTTPUtility

    def self.request_signature_from_request(net_http, request, body = nil)
      ...

在同一文件的第 75 行调用:

def request(request, body = nil, &block)
  request_signature = WebMock::NetHTTPUtility.request_signature_from_request(self, request, body)

这是我在客户端调用的方法。这些是我的文件:

net_http.rb

class NetHttp

  def initialize(client)
    @client = client
  end

  def request(request)
    client.request(request)
  end

  private

  attr_reader :client

end

net_http_spec.rb

describe "NetHttp" do

  let(:client)   {Net::HTTP.new(VERIFY_URL.host, VERIFY_URL.port)}
  let(:net_http) {NetHttp.new(client)}

  it "sends a get request" do
    request  = request_with_path
    response = net_http.request(request)
    expect(response.code).to eq("200")
  end

  def request_with_path
    request = stub_request(:get, VERIFY_URL)
      .with(:headers => {
        'Accept'=>'*/*',
        'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
        'User-Agent'=>'Ruby'
        })
      .to_return(:status => 200, :body => '{"hello": "world"}', :headers => {})

    class << request
      attr_accessor :path
    end

    request.path = VERIFY_URL.request_uri
    request
  end

end

我动态添加属性的最后一部分是解决另一个错误。感觉有点像一个肮脏的黑客。也许有更好的方法来做这一切,这也会阻止我这样做?

在我的 spec_helper.rb 中我添加了以下行:

WebMock.disable_net_connect!(allow_localhost: true)

我已将请求的内容放入 request 方法中,一切似乎都很好,我还使用了 Net::HTTPRequest 的两倍而不是 webmock 存根,但我得到了同样的错误。我不想存根客户端,因为那是我正在测试的系统。我还查看了 Ruby 文档中的 request 方法的代码。我不明白...该错误来自哪里以及如何解决?

【问题讨论】:

  • 尝试使用 -b 选项运行 rspec(默认情况下,rspec 会隐藏部分回溯,而不是来自您的应用程序,这可能会让您看错地方)
  • @FrederickCheung 我已经更新了错误信息。
  • 看起来你的假请求对象没有 method 方法,所以它从 Object 调用 method 方法,它确实需要一个参数
  • 我走上了这条路,但它只是不断地要求别的东西,比如 body_streamread 方法等等,等等。

标签: ruby http rspec sinatra webmock


【解决方案1】:

您不需要照原样使用stub_request 的返回值。您可以像往常一样构造Net::HTTP::Request 的实例。

【讨论】:

  • 对不起,我不明白...我需要将请求对象传递给请求方法。在生产环境中创建它的方式是这样的:request = Net::HTTP::Get.new VERIFY_URL.request_uri,但如果我通过了,Webmock 会提醒我 Real HTTP 连接被禁用。我不想在方法内调用new,因为我想使用依赖注入。
  • Webmock 文档建议应该没问题。也许您错误地存根请求? (例如 VERIFY_URL 是什么)
  • VERIFY_URL 是一个字符串,其中包含一个 URI 对象以及我想连接到的 URL。我的理解是 webmock 将捕获对该 URL 的请求并返回存根响应。
  • 看起来它是一个实际的 URI 对象,这可能不是 webmock 所期望的 - 文档暗示它只是一个字符串
  • 我终于明白你的答案了。当我执行response = net_http.request(request) 时,它会自动使用存根。因此,如果我删除测试的第一行和存根的分配,它会起作用:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 2019-02-08
  • 2016-08-12
  • 2020-09-24
  • 2017-09-12
  • 2019-01-22
相关资源
最近更新 更多