We connect our Rails 3.2 application to ElasticSearch with the famous Tire-Gem. After each save of an indexed object rails calls ElasticSearch via http in sends the new object data. But this behaviour produces quite a lot of overhead in our test suite. In most of the tests we don’t need ElasticSearch and therefore don’t want the objects to be indexed. I found this Gist which mocks ElasticSearch Calls with Webmock. It looks slightly complicated on first sight but works quite fine. The problem is: we also use capybara-webkit for feature tests. And Capybara does HTTP-Calls to the webkit-server. Webmock blocks these requests too. After some research I found a far easier solution: Fakeweb. While Webmock blocks all HTTP calls during the tests, Fakeweb only fakes results on previously defined URLs or URL-patterns. This led me to the following solution:
Add the fakeweb-gem to your Gemfile:
gem 'fakeweb', group :test
Then add the following around-block to your spec_helper.rb
, assuming there is one indexed model called Contact
:
config.around :each do |example|
if example.metadata[:elasticsearch]
Contact.tire.index.delete # delete the index for a clean environment
example.run
else
FakeWeb.register_uri :any, %r(#{Tire::Configuration.url}), body: '{}'
example.run
FakeWeb.clean_registry
end
end
Calls to ElasticSearch are hereby disabled. If you need ElasticSearch to test your searching functionality add the elasticsearch metadata to your tests:
it 'finds a contact', elasticsearch: true do
contacts = Contact.search('bruce')
contacts.should include @contact
end
With this solution our tests were about 15-20% faster.