Elasticsearch out of sync when overwhelmed on HTTP at test suite
Your test is confused - it's testing assignment, pagination, and (implicitly) parameter passing. Break it out:
Parameters
let(:tire) { double('tire', :search => :sentinel) }it 'passes the correct parameters to Companies.tire.search' do expected_params = ... # Some transformation, if any, of params Companies.stub(:tire).with(tire) get :index, params expect(tire).to have_received(:search).with(expected_params)end
Assignment
We are only concerned that the code is taking one value and assigning it to something else, the value is irrelevant.
it 'assigns the search results to companies' do Companies.stub(:tire).with(tire) get :index, params expect(assigns[:companies]).to eq :sentinelend
Pagination
This is the tricky bit. You don't own the ES API, so you shouldn't stub it, but you also can't use a live instance of ES because you can't trust it to be reliable in all testing scenarios, it's just an HTTP API after all (this is the fundamental issue you're having). Gary Bernhardt tackled this issue in one of his excellent screencasts - you simply have to fake out the HTTP calls. Using VCR:
VCR.use_cassette :tire_companies_search do get :index, params search_result_length = assigns[:companies].length expect(search_result_length).to eq 2end
Run this once successfully then forever more use the cassette (which is simply a YAML file of the response). Your tests are no longer dependent on APIs you don't control. If ES or your pagination gem update their code, simply re-record the cassette when you know the API is up and working. There really isn't any other option without making your tests extremely brittle or stubbing things you shouldn't stub.
Note that although we have stubbed tire
above - and we don't own it - it's ok in these cases because the return values are entirely irrelevant to the test.