模拟 GoogleAPI 请求
Mock GoogleAPI request
我正在使用 google-maps gem.
我正在尝试 mock/stub api 请求失败。
module GoogleMap
class Route
attr_accessor :start_location, :end_location
def initialize(start_location, end_location)
@start_location = start_location
@end_location = end_location
end
def driving_duration_in_seconds
route.duration.value
end
def driving_distance_in_meters
route.distance.value
end
def driving_distance_hash
return unless start_location && end_location
{ distance_in_meters: driving_distance_in_meters, duration_in_seconds: driving_duration_in_seconds }
end
private
def coordinates_as_strings(location)
"#{location.latitude},#{location.longitude}"
end
def route
@route ||= Google::Maps.route(coordinates_as_strings(start_location), coordinates_as_strings(end_location))
end
end
end
我需要存根:
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET https://maps.googleapis.com/maps/api/directions/json?destination=37.19687112,116.43791248&key=<apikey>&language=en&origin=2.15362819,-81.63712649 with headers {'Accept'=>'*/*', 'Date'=>'Sat, 12 Feb 2022 21:35:55 GMT', 'User-Agent'=>'HTTPClient/1.0 (2.8.3, ruby 2.7.2 (2020-10-01))'}
You can stub this request with the following snippet:
stub_request(:get, "https://maps.googleapis.com/maps/api/directions/json?destination=37.19687112,116.43791248&key=<apikey>&language=en&origin=2.15362819,-81.63712649").
with(
headers: {
'Accept'=>'*/*',
'Date'=>'Sat, 12 Feb 2022 21:35:55 GMT',
'User-Agent'=>'HTTPClient/1.0 (2.8.3, ruby 2.7.2 (2020-10-01))'
}).
to_return(status: 200, body: "", headers: {})
如果我尝试最基本的存根,我会得到一个错误:
stub_request(:any, /maps.googleapis.com/).
to_return(status: 200, body: '', headers: {})
Google::Maps::InvalidResponseException:
unknown error: 783: unexpected token at ''
# .../gems/ruby-2.7.2/gems/google-maps-3.0.7/lib/google_maps/api.rb:64:in `rescue in response'
# .../gems/ruby-2.7.2/gems/google-maps-3.0.7/lib/google_maps/api.rb:60:in `response'
# .../.rvm/gems/ruby-2.7.2/gems/google-maps-3.0.7/lib/google_maps/api.rb:27:in `query'
我认为这是错误的,因为我没有传递密钥。但我不明白为什么我必须将有效的 api 密钥传递到网络模拟中。
我也不会用任何东西来定义我的路线。为了测试 route
可以 return route.distance.value
等,我需要模拟一些东西。
对于其他测试,我在模拟实例方面是成功的,但是为了测试这个 lib 它确实有效,我觉得模拟实例方法而不是实际调用 api 是浪费测试。也许这只是浪费时间,我应该假设它有效,因为我使用的是 gem.
但我期待这样的事情:
RSpec.describe GoogleMap do
let(:start_location) { create(:location) }
let(:end_location) { create(:location) }
context 'GoogleMaps::Route.new(start_location, end_location)' do
let(:subject) { GoogleMap::Route.new(start_location, end_location) }
# I have not been successful in stubbing this with the correct regex
# stub_request(:get, "https://maps.googleapis.com/maps/api/directions/json?destination=<lat>,<long>key=<key>&language=en&origin=<lat>,<long>").
# with(
# headers: {
# 'Accept'=>'*/*',
# 'Date'=>'Thu, 10 Feb 2022 21:09:02 GMT',
# 'User-Agent'=>'HTTPClient/1.0 (2.8.3, ruby 2.7.2 (2020-10-01))'
# }).
# to_return(status: 200, body: "", headers: {})
# stub_request(:get, %r{https:\/\/maps\.googleapis\.com\/maps\/api\/directions\/json\?destination=.+,.+&key=.+&language=en&origin=.+,.+}).
# stub_request(:any, /maps.googleapis.com/).
# to_return(status: 200, body: '', headers: {})
xit 'gives driving distance in seconds'
xit 'gives driving duration in meters'
end
end
您的 WebMock 工作正常。 Google::Maps::InvalidResponseException
在 WebMock 替换网络调用后引发。在引发异常时,Google Maps API 客户端正在尝试解析网络调用 returned 的内容,即 ''
.
它期待一些 valid JSON to be returned。如果你有你的模拟 return {}
应该越过那条线。不过,它稍后可能会偶然发现其他一些异常,因为 gem 需要特定的模式。
如果你想继续沿着这条路走下去,你可以挖掘出来并添加一个有效的回复。但是,我建议不要模拟网络请求,因为这是第三方代码片段的实现细节,可能随时更改 - 使您的测试失败。相反,我会模拟出 Google::Maps.route
到 return 你需要的东西。
我正在使用 google-maps gem.
我正在尝试 mock/stub api 请求失败。
module GoogleMap
class Route
attr_accessor :start_location, :end_location
def initialize(start_location, end_location)
@start_location = start_location
@end_location = end_location
end
def driving_duration_in_seconds
route.duration.value
end
def driving_distance_in_meters
route.distance.value
end
def driving_distance_hash
return unless start_location && end_location
{ distance_in_meters: driving_distance_in_meters, duration_in_seconds: driving_duration_in_seconds }
end
private
def coordinates_as_strings(location)
"#{location.latitude},#{location.longitude}"
end
def route
@route ||= Google::Maps.route(coordinates_as_strings(start_location), coordinates_as_strings(end_location))
end
end
end
我需要存根:
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET https://maps.googleapis.com/maps/api/directions/json?destination=37.19687112,116.43791248&key=<apikey>&language=en&origin=2.15362819,-81.63712649 with headers {'Accept'=>'*/*', 'Date'=>'Sat, 12 Feb 2022 21:35:55 GMT', 'User-Agent'=>'HTTPClient/1.0 (2.8.3, ruby 2.7.2 (2020-10-01))'}
You can stub this request with the following snippet:
stub_request(:get, "https://maps.googleapis.com/maps/api/directions/json?destination=37.19687112,116.43791248&key=<apikey>&language=en&origin=2.15362819,-81.63712649").
with(
headers: {
'Accept'=>'*/*',
'Date'=>'Sat, 12 Feb 2022 21:35:55 GMT',
'User-Agent'=>'HTTPClient/1.0 (2.8.3, ruby 2.7.2 (2020-10-01))'
}).
to_return(status: 200, body: "", headers: {})
如果我尝试最基本的存根,我会得到一个错误:
stub_request(:any, /maps.googleapis.com/).
to_return(status: 200, body: '', headers: {})
Google::Maps::InvalidResponseException:
unknown error: 783: unexpected token at ''
# .../gems/ruby-2.7.2/gems/google-maps-3.0.7/lib/google_maps/api.rb:64:in `rescue in response'
# .../gems/ruby-2.7.2/gems/google-maps-3.0.7/lib/google_maps/api.rb:60:in `response'
# .../.rvm/gems/ruby-2.7.2/gems/google-maps-3.0.7/lib/google_maps/api.rb:27:in `query'
我认为这是错误的,因为我没有传递密钥。但我不明白为什么我必须将有效的 api 密钥传递到网络模拟中。
我也不会用任何东西来定义我的路线。为了测试 route
可以 return route.distance.value
等,我需要模拟一些东西。
对于其他测试,我在模拟实例方面是成功的,但是为了测试这个 lib 它确实有效,我觉得模拟实例方法而不是实际调用 api 是浪费测试。也许这只是浪费时间,我应该假设它有效,因为我使用的是 gem.
但我期待这样的事情:
RSpec.describe GoogleMap do
let(:start_location) { create(:location) }
let(:end_location) { create(:location) }
context 'GoogleMaps::Route.new(start_location, end_location)' do
let(:subject) { GoogleMap::Route.new(start_location, end_location) }
# I have not been successful in stubbing this with the correct regex
# stub_request(:get, "https://maps.googleapis.com/maps/api/directions/json?destination=<lat>,<long>key=<key>&language=en&origin=<lat>,<long>").
# with(
# headers: {
# 'Accept'=>'*/*',
# 'Date'=>'Thu, 10 Feb 2022 21:09:02 GMT',
# 'User-Agent'=>'HTTPClient/1.0 (2.8.3, ruby 2.7.2 (2020-10-01))'
# }).
# to_return(status: 200, body: "", headers: {})
# stub_request(:get, %r{https:\/\/maps\.googleapis\.com\/maps\/api\/directions\/json\?destination=.+,.+&key=.+&language=en&origin=.+,.+}).
# stub_request(:any, /maps.googleapis.com/).
# to_return(status: 200, body: '', headers: {})
xit 'gives driving distance in seconds'
xit 'gives driving duration in meters'
end
end
您的 WebMock 工作正常。 Google::Maps::InvalidResponseException
在 WebMock 替换网络调用后引发。在引发异常时,Google Maps API 客户端正在尝试解析网络调用 returned 的内容,即 ''
.
它期待一些 valid JSON to be returned。如果你有你的模拟 return {}
应该越过那条线。不过,它稍后可能会偶然发现其他一些异常,因为 gem 需要特定的模式。
如果你想继续沿着这条路走下去,你可以挖掘出来并添加一个有效的回复。但是,我建议不要模拟网络请求,因为这是第三方代码片段的实现细节,可能随时更改 - 使您的测试失败。相反,我会模拟出 Google::Maps.route
到 return 你需要的东西。