2016-05-18 10 views
0

'ApiClient.do_request'が正しい引数を送信し、 'RestClient :: Request.execute'を呼び出していることをテストしようとしています。しかし、以下の仕様は意図したとおりに動作していません。 RSpecは、メソッドの 'response'変数がnilとして戻ってくるので、RestClient :: Request.executeを適切に呼び出すことができません。JSON.parse(レスポンス)が呼び出されたときに以下のようなTypeErrorが返されます。私にとって奇妙なのは、Railsコンソールのプロセスを歩いても問題がないということです。確かに私はここで紛失していることが明らかです...なぜこれが起こっているのか、あるいはこれをもっと効果的にテストする方法についての提案ですか?RSpecでRestClient :: Request.executeをテストする

モデル:

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 

仕様:

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のエラー:

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

RSpecエラーは別のテストのようです。すなわち、 "場所 'オプション'が要求されたときに 'オプション'引数*を受け取ります。 – Uzbekjon

+0

実際には同じテストですが、古いバージョンのエラーメッセージが誤って含まれています。更新されたテスト名を反映するために上記のRSpecエラーを更新しました。 –

答えて

1

があなたのApiClientクラスでapi_version=2.0&app_id=ShowBoatのようなマイナーな構文エラーを考慮していない、問題が発生しているように見えますRestClient::Request.executeリクエストで返信するnil

responseの値をデバッグまたは検査し、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 

、あなたはApiClientクラスの実装をテストしています。言い換えれば、クラスが内部的に特定の方法で他のクラスを呼び出すことをテストしています。たとえば、後でRestClientをHTTPartyに置き換えることに決めた場合、テストは失敗します(クラスはまだ正常に動作しているので、テストしてはいけません)。

したがって、クラスの実装をテストすることで、テストが「脆弱」になります。代わりに、入力を与え、予想される正しい出力をテストします。

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

私はまだ '応答'変数がnilとして返され続けている理由についてまだ疑問に思っていますが、テストの脆弱性に関するフィードバックは私が疑ったものです。それが現れているように、より柔軟にテストを変更する必要があるように感じます。ありがとうございました! –

関連する問題