测试 RestClient::Request. 在 RSpec 中执行
Testing RestClient::Request.execute in RSpec
我正在尝试测试 'ApiClient.do_request' 是否正在发送正确的参数并调用 'RestClient::Request.execute.' 但是,我的以下规格没有按预期工作。 RSpec 无法正确调用 'RestClient::Request.execute,',因为方法的 'response' 变量不断返回为 nil,这就是为什么在调用 JSON.parse(response) 时出现以下 TypeError 的原因。让我感到奇怪的是,在 Rails 控制台中完成整个过程时我没有遇到任何问题。我确定我在这里遗漏了一些明显的东西......为什么会发生这种情况,或者关于如何更有效地测试它的任何想法?
型号:
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)>'
没有考虑 ApiClient
class 中的 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
class 的实施。换句话说,您正在测试 class 是否以特定方式在内部调用其他 class。例如,如果您决定稍后用 HTTParty 替换 RestClient,您的测试将失败(即使它们不应该失败,因为您的 class 仍在正常工作)。
因此,测试 class 的实现会使您的测试成为 "fragile"。相反,提供输入并测试预期的正确输出。
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
我正在尝试测试 'ApiClient.do_request' 是否正在发送正确的参数并调用 'RestClient::Request.execute.' 但是,我的以下规格没有按预期工作。 RSpec 无法正确调用 'RestClient::Request.execute,',因为方法的 'response' 变量不断返回为 nil,这就是为什么在调用 JSON.parse(response) 时出现以下 TypeError 的原因。让我感到奇怪的是,在 Rails 控制台中完成整个过程时我没有遇到任何问题。我确定我在这里遗漏了一些明显的东西......为什么会发生这种情况,或者关于如何更有效地测试它的任何想法?
型号:
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)>'
没有考虑 ApiClient
class 中的 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
class 的实施。换句话说,您正在测试 class 是否以特定方式在内部调用其他 class。例如,如果您决定稍后用 HTTParty 替换 RestClient,您的测试将失败(即使它们不应该失败,因为您的 class 仍在正常工作)。
因此,测试 class 的实现会使您的测试成为 "fragile"。相反,提供输入并测试预期的正确输出。
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