I'm attempting to stub a request to a Controller using WebMock. However, as I'm creating the stub, the request isn't being intercepted the way I'd expect or want it to be.
The Controller does nothing but render JSON based on the query parameter:
def index
render json: MyThing.search(params[:query]).as_json(only: [:id], methods: [:name_with_path])
end
And the stubbing goes as follows:
mything_val = { ...json values... }
stub_request(:any, mything_path).with(query: { "query" => "a+thing" }).to_return(body: mything_val, status: 200)
page.find('.MyThingInput > input').set('a thing')
# Note: I've tried this with and without the `query:` parameter, as well as
with and without specifying header info.
This is triggering a React component. What it does is, when a word or words are entered into the input, it sends an AJAX request to mything_path with the inputted value, which returns as JSON several suggestions as to what the user might mean. These are in a li
element within .MyThingInput-wrapper
.
In the spec file, I include:
require 'support/feature_helper'
require 'support/feature_matchers'
require 'webmock/rspec'
WebMock.disable_net_connect!
What's actually happening when I input the text into the React component however is that regardless of the WebMock stub, it's hitting the Controller, making the DB request, and failing due to some restrictions of the testing environment. My understanding of how this should work is that when the request is made to mything_url, it should be intercepted by WebMock which would return the values I pre-defined, and never hit the Controller at all.
My guess is that somehow I'm mocking the wrong URI, but honestly, at this point I'm really uncertain. Any and all input is appreciated, and I'm happy to clarify any points I've made here. Thanks massively!
What ended up solving my problem was stubbing out the model. I'd tried stubbing the Controller but ran into issues; however, this code did the trick:
before do
mything_value = [{ "id" => "fb6135d12-e5d7-4e3r-b1h6-9bhirz48616", "name_with_path" => "New York|USA" }]
allow(MyThing).to receive(:search).and_return(mything_value.to_json)
end
This way, it still hits the controller but stubs out the DB query, which was the real problem because it made use of Elasticsearch (not running in test mode.)
I'm not super happy about hard-coding the JSON like that, but I've tried a few other methods without success. Honestly, at this point I'm just going with what works.
Interestingly enough, I'd tried this method before Infused's suggestion, but couldn't quite get the syntax right; same went with stubbing out the Controller action. Went to bed, woke up, tried it again with what I thought was the same syntax, and it worked. I'm just going to slowly back away and thank the code gods.