Open janko opened 8 years ago
wow, I never thought of that! nice :)
This can be documented as long as we add an acceptance spec to cover that scenario and it passes across all supported http clients.
Actually, I misread, it only yields only one chunk equal to ["a", "b", "c"]
(I used puts
instead of p
, so I thought I was getting the right result). Maybe this could be a feature, but I guess it would take a lot of work to port it to all other adapters.
In the meanwhile I managed to create a workaround, so posting here in case anyone's interested:
before do
mocked_http = Class.new(Net::HTTP) do
def request(*)
super do |response|
response.instance_eval do
def read_body(*, &block)
@body.each_char(&block)
end
end
yield response if block_given?
response
end
end
end
@original_net_http = Net.send(:remove_const, :HTTP)
Net.send(:const_set, :HTTP, mocked_http)
end
after do
Net.send(:remove_const, :HTTP)
Net.send(:const_set, :HTTP, @original_net_http)
end
A slightly modified @janko's example from above, which avoids instance variable in spec, and expects stubbed body
to be an array, where each array element will yield the the block passed to read_body
:
let(:mock_net_http) do
Class.new(Net::HTTP) do
def request(*)
super do |response|
response.instance_eval do
def read_body(*, &)
@body.each(&)
end
end
yield response if block_given?
response
end
end
end
end
let(:remove_original_net_http) { Net.send(:remove_const, :HTTP) }
let(:original_http) { remove_original_net_http }
let(:stub_net_http) { Net.send(:const_set, :HTTP, mock_net_http) }
let(:remove_stubbed_net_http) { Net.send(:remove_const, :HTTP) }
let(:restore_net_http) { Net.send(:const_set, :HTTP, original_http) }
before do
mock_net_http
remove_original_net_http
stub_net_http
# Stub response body as an array of chunks
stub_request(:post, "OpenAI url").to_return(status: 200, body: ["first chunk", "second chunk"])
end
after do
remove_stubbed_net_http
restore_net_http
end
@pjg thanks a lot, save my day!
:hugs: thanks, very helpful wish this was built in.
hopes and prayers :) https://meta.discourse.org/discourse-ai/ai-bot/shared-ai-conversations/ZRd74GXAe7KhS1pUqcQ3nw
Will try to wire up a PR tomorrow... who knows how well this will do...
For the record... AI was sadly zero help here... made a PR :)
With WebMock I needed to test streaming response body with net/http, so I wanted to set specific chunks which will be yielded when I run the following code:
I was reading a bit of WebMock source code, but I couldn't find anything that might indicate existence of this feature. So at the end I just tried out the following, knowing that it probably wouldn't work:
But it worked! This made me really happy! I just thought it would be great to document this feature in the README.
Absolutely awesome library, thank you! ❤️