2016-05-18 4 views
0

J'essaie de tester que 'ApiClient.do_request' envoie les arguments corrects et appelle 'RestClient :: Request.execute.' Cependant, mes spécifications ci-dessous ne fonctionnent pas comme prévu. RSpec est incapable d'appeler correctement 'RestClient :: Request.execute', car la variable 'response' de la méthode continue de revenir à zéro, ce qui explique pourquoi j'obtiens le TypeError ci-dessous lorsque JSON.parse (response) est appelée. Ce qui est étrange à mes yeux, c'est que je n'ai aucun problème à parcourir le processus dans la console Rails. Je suis sûr qu'il y a quelque chose d'évident qui me manque ici ... Des idées pour lesquelles cela se produit, ou peut-être des suggestions sur la façon dont je peux tester cela plus efficacement?Test RestClient :: Request.execute dans RSpec

Modèle:

class ApiClient < ActiveRecord::Base 

    BASE_PATH = "http://api.bandsintown.com/artists/" 
    APP_ID = ENV["APP_ID"] 

    def do_request(method:, base_url:BASE_PATH, app_id:APP_ID, url:, format:"json", options: nil) 
    response = RestClient::Request.execute(method: method.to_sym, 
              url: "#{base_url}#{url}.#{format}?api_version=2.0&app_id=#{app_id}#{options}", 
              timeout: 10) 

    JSON.parse(response) 
    end 

Spec:

describe ApiClient do 

    describe "do_request" do 

    context "when all required arguments are present" do 
     it "RestClient executes the request" do 
     @test_client = ApiClient.new 

     expect(RestClient::Request).to receive(:execute).with(:method=>:get, :url=> "http://api.bandsintown.com/artists/Damien%20Jurado/events/search.json?api_version=2.0&app_id=ShowBoatTest&location=San+Diego,CA&radius=15", :timeout=>10) 

     @test_client.do_request(method:"get", app_id:"ShowBoatTest",url:"Damien%20Jurado/events/search",options:"&location=San+Diego,CA&radius=15") 
     end 
    end 
    end 

RSpec Erreur:

1) ApiClient do_request when all required arguments are present RestClient executes the request 
Failure/Error: JSON.parse(response) 

TypeError: 
    no implicit conversion of nil into String 
# /Users/slamflipstrom/.rvm/gems/ruby-2.1.5/gems/json-1.8.3/lib/json/common.rb:155:in `initialize' 
# /Users/slamflipstrom/.rvm/gems/ruby-2.1.5/gems/json-1.8.3/lib/json/common.rb:155:in `new' 
# /Users/slamflipstrom/.rvm/gems/ruby-2.1.5/gems/json-1.8.3/lib/json/common.rb:155:in `parse' 
# ./app/models/api_client.rb:12:in `do_request' 
# ./spec/models/api_client_spec.rb:13:in `block (4 levels) in <top (required)>' 
+2

L'erreur RSpec semble provenir d'un autre test. A savoir "* lorsque les options 'location' sont demandées reçoit un argument 'options' *". – Uzbekjon

+0

Ils sont en fait le même test, mais j'ai inclus par erreur le message d'erreur d'une ancienne version de celui-ci. J'ai mis à jour l'erreur RSpec ci-dessus pour refléter le nom de test mis à jour. –

Répondre

1

Ne pas tenir compte des erreurs de syntaxe mineures comme api_version=2.0&app_id=ShowBoat dans votre ApiClient classe, le problème semble être causé par votre RestClient::Request.execute demande renvoyant nil.

Déboguez ou inspectez la valeur de response et assurez-vous que ce n'est pas nil.

class ApiClient < ActiveRecord::Base 

    BASE_PATH = "http://api.bandsintown.com/artists/" 
    APP_ID = ENV["APP_ID"] 

    def do_request(method:, base_url:BASE_PATH, app_id:APP_ID, url:, format:"json", options: nil) 
    response = RestClient::Request.execute(method: method.to_sym, 
              url: "#{base_url}#{url}.#{format}?api_version=2.0&app_id=#{app_id}#{options}", 
              timeout: 10) 
    puts response.inspect 
    response ? JSON.parse(response) : [] 
    end 

D'autre part, vous testez la mise en œuvre de ApiClient classe. En d'autres termes, vous testez que la classe appelle en interne une autre classe de manière spécifique. Si vous décidez de remplacer le RestClient par HTTParty par exemple ultérieurement, vos tests échoueront (même s'ils ne le devraient pas, car votre classe fonctionne toujours correctement). Ainsi, en testant la mise en œuvre de la classe, vos tests sont "fragiles". Au lieu de cela, donnez une entrée et testez la sortie correcte attendue.

describe ApiClient do 
    context "with all required arguments" do 
    describe "#do_request" do 
     it "returns object in correct format" do 
     response = subject.do_request(method:"get", app_id:"ShowBoatTest",url:"Damien%20Jurado/events/search",options:"&location=San+Diego,CA&radius=15") 
     expect(response.body).to include(title: "Damien Jurado @ The Casbah in San Diego, CA") 
     # etc. 
     end 
    end 
    end 
end 
+0

Je suis toujours perplexe quant à la raison pour laquelle la variable «réponse» continue à être retourné comme nulle, mais les commentaires concernant la fragilité du test est ce que je soupçonnais. En l'état, j'ai l'impression que je devrais simplement changer le test pour être plus flexible. Je vous remercie! –