我试图在我的测试套件中存根任何外部API调用,但是从不执行before(:suite)。 Webmock总是报告我需要存储maps.googleapis.com,即使还没有运行测试(没有绿点,没有红色F)。
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
...
config.before(:suite) do
puts "THIS NEVER SHOWS"
stub_request(:get, "maps.googleapis.com").
with(headers: {'Accept'=>'*/*', 'User-Agent'=>'Ruby'}).
to_return(status: 200, body: "", headers: {})
end
geocoder gem最终试图从googleapis.com保存lat / lon,并且Webmock提出错误,说该URL未注册。
编辑:错误代码段:
$ bundle exec rspec spec/factories_spec.rb
/home/jake/.rvm/gems/ruby-2.1.0@global/gems/webmock-1.17.4/lib/webmock/http_lib_adapters/net_http.rb:114:in `request': Real HTTP connections are disabled. Unregistered request: GET http://maps.googleapis.com/maps/api/geocode/json?address=[private]&language=en&sensor=false with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'} (WebMock::NetConnectNotAllowedError)
You can stub this request with the following snippet:
stub_request(:get, "http://maps.googleapis.com/maps/api/geocode/json?address=[private]&language=en&sensor=false").
with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}).
to_return(:status => 200, :body => "", :headers => {})
============================================================
from /home/jake/.rvm/gems/ruby-2.1.0@global/gems/geocoder-1.1.9...
...
同样,我强调这与config.before(:each)块中的代码永远不会运行这一事实有关。为什么?因为如果是的话,我可以“提升”WTF'"和' WTF'应出现在控制台输出中,而不是您在上面看到的错误。我只看到了WTF'当我" un-bundle" Webmock的宝石。
答案 0 :(得分:1)
我通过RSpec测试做了“可爱的事”,在运行时创建测试,具体取决于Factory是否具有属性文件。由于我的工厂/模型的设置方式,当正在读取某个工厂的属性时,正在创建(保存)工厂,因此生成测试的代码块在RSpec的config.before(:suite)之外运行并且WebMock引发了错误。
https://github.com/bblimke/webmock/issues/378
此外,这里特别是我做错了 - 与WebMock无关:
1)在我的factories.rb中,我正在为可能尚不存在的关联调用create()。为什么?因为RSpec给我的错误说“[关联]是空白的”。这样做是因为我有validates_presence_of:association_id而不仅仅是:association。当我使用create()而不是build()时,它“工作”了。当然,到了使用WebMock的时候,我正在创建(并因此保存)调用地理编码器的对象来做这件事。解决方案是修复validates_presence_of以使用正确的属性,并在我的工厂中使用build()而不是create()。
错误示例:
# In spec/factories.rb
factory :review, class: Manager::Review do
rating 4
wine { Manager::Wine.first || create(:wine) }
reviewer { Manager::Reviewer.first || create(:reviewer) }
date Time.now
association :referral, referrable_id: 1, referrable_type: Manager::Review, strategy: :build
end
# In app/models/manager/review.rb
validates_presence_of :rating_id, :wine_id, :reviewer_id, :date
好例子:
# In spec/factories.rb
factory :review, class: Manager::Review do
rating 4
wine { Manager::Wine.first || build(:wine) }
reviewer { Manager::Reviewer.first || build(:reviewer) }
date Time.now
association :referral, referrable_id: 1, referrable_type: Manager::Review, strategy: :build
end
# In app/models/manager/review.rb
validates_presence_of :rating, :wine, :reviewer, :date
2)FWIW,我告诉地理编码器在pre_save中获取地理编码,而不是像在主页中建议的那样使用after_validate。
另外,你不能在before(:suite)中使用WebMock存根,但它可以在before(:each)之前使用