2016-06-22 1 views
1

Dans une application Sinatra, j'essaie de créer mon propre wrapper autour de Net::HTTP, mais je suis bloqué à l'un de mes tests. J'utilise Webmock pour remplacer une requête et la passer à la méthode request de Net::HTTP. Je fais les tests avec RSpec. L'erreur que je reçois est:mauvais nombre d'arguments dans la requête Net :: HTTP

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>' 

Ligne 279 de net_http.rb (la première ligne de la pile) est la suivante:

method = request.method.downcase.to_sym 

qui se trouve dans la méthode:

module WebMock 
    module NetHTTPUtility 

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

qui est appelé à la ligne 75 du même fichier:

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

qui est la méthode que j'appelle sur mon client. Ce sont mes fichiers:

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 

La dernière partie où j'ajouter un attribut à la volée était de résoudre une autre erreur. Cela ressemble un peu à un bidouillage sale. Peut-être qu'il y a une meilleure façon de faire tout cela, cela m'empêchera aussi de faire ça?

Et dans mon spec_helper.rb j'ai ajouté la ligne:

WebMock.disable_net_connect!(allow_localhost: true) 

J'ai mis le contenu de la demande dans la méthode request et tout semble être ok, je l'ai aussi utilisé un double de Net::HTTPRequest au lieu d'un stub webmock, mais j'ai la même erreur. Je ne veux pas talonner le client parce que c'est mon système en test. J'ai également regardé le code de la méthode request dans les docs Ruby. Je ne comprends pas ... d'où vient cette erreur et comment la résoudre?

+0

Essayez d'exécuter rspec avec l'option -b (par défaut, rspec cache les parties du backtrace qui ne sont pas dans votre application, ce qui peut vous faire regarder au mauvais endroit) –

+0

@FrederickCheung J'ai mis à jour le message d'erreur. –

+0

On dirait que votre faux objet de requête n'a pas de méthode 'method' donc il appelle la méthode' method' de Object qui attend vraiment un argument –

Répondre

0

Vous n'avez pas besoin d'utiliser la valeur de retour de stub_request comme vous êtes. Vous pouvez construire une instance de Net::HTTP::Request comme d'habitude.

+0

Désolé, je ne comprends pas ... J'ai besoin de passer un objet de requête à la méthode de requête. La façon dont il va être créé en production est comme ceci: 'request = Net :: HTTP :: Get.new VERIFY_URL.request_uri', mais si je le transmets, Webmock m'avertit que les connexions HTTP réelles sont désactivées. Je ne veux pas avoir d'appels à 'new' dans la méthode parce que je veux utiliser l'injection de dépendance. –

+0

Docs Webmock suggèrent que cela devrait aller. Peut-être que vous réduisez la demande incorrectement? (Par exemple ce qui est VERIFY_URL) –

+0

VERIFY_URL est une chaîne qui contient un objet URI avec l'URL à laquelle je voudrais me connecter.Ma compréhension est que webmock va attraper des demandes à cette URL et retourner la réponse stubbed. –