提示:模拟Web APIs
如果你与任何基于网络的服务进行交互,你需要模拟你的请求以正确测试你的程序。在现实中,有两种方法来模拟你的外部请求。
- 你保存响应,例如使用类似VCR的东西,或者
- 使用类似Webmock API的东西来模拟请求。
使用VCR保存响应
VCR是一个非常酷的工具,它允许你在第一次调用它的时候重放任何HTTP交互,这个想法是无论如何都要有相同的响应,因为你实际上是把产生的响应保存到一个文件中,一个卡带。
配置,在这种情况下,使用webmock作为存根设施,是这样的。
VCR.configure do |config|
config.configure_rspec_metadata!
config.cassette_library_dir = File.expand_path(File.join('..', 'cassettes'),
__FILE__)
config.hook_into :webmock
end
显然,你的具体cassette_library_dir ,取决于你的环境,但你会明白这个意思。
在Rspec中,要使用它,你会做这样的事情。
describe '#some_method', vcr: { cassette_name: 'my_request' } do
it 'here I request whatever url I need to' do
# fun stuff
end
end
这个规范将创建一个文件my_request.yml ,其中包含所有执行时请求的HTTP信息,包括实际的响应,它将使用这个相同的文件来模拟运行你的测试所需的HTTP对象,所以它将始终给你相同的响应。
使用Webmock模拟响应
在你实际上没有预定义的URL来请求的情况下,因为也许你的程序根据响应代码来处理不同的响应,你将需要明确地模拟这个请求。为此,你需要直接使用webmock。
在这种情况下,启用webmock比使用VCR要复杂一些,但仍然不是那么复杂。你需要做三件事。
1.实现一个处理实际请求的Sinatra应用程序
require 'sinatra/base'
class DummyApp < Sinatra::Base
get '/' do
'hello'
end
end
2.2.配置RSpec,用该Sinatra应用程序存根特定域。
RSpec.configure do |config|
config.include WebMock::API
config.before(:each) do
stub_request(:any, /mocked-domain.com/).to_rack(DummyApp)
end
end
3.在你的规范中使用它
describe '#some_method' do
it 'here I request mocked-domain.com/hello' do
# fun stuff
end
end
总结
了解处理(和模拟)外部Web服务的两种方法是非常有用的,因为它可以让你获得确定的结果。在围绕外部Web服务构建程序时,非常有用。