Closed ioquatix closed 5 months ago
@ayanko @bblimke here is a rough POC showing how to use an endpoint and an internal HTTP connection/server (using HTTP2 by default) to easily intercept requests. It's inspired by @ayanko's webmock implementation, but I wanted to try and standardise some of it.
The next step is to try and figure out what Async::HTTP::Mock::Client
should look like. Either, 1/ something which lets you stub in client side request/response with delegation to the server connection if required, or 2/ just doing everything on the server, proxying requests as needed.
Personally, while 2/ is simpler, the chance of it breaking things is higher, because we'd need to correctly proxy WebSockets, HTTPS, etc, it's basically a man in the middle. But because of that, it's a centralised place for the logic to go.
It's all in the same process. @ayanko see #35 for more discussion if you are interested.
The other part of this, is the ability to replace Async::HTTP::Client
, which I'm happy to leave in WebMock since it's kind of a hack and maybe shouldn't be officially sanctioned (but unofficially allowed as per normal Ruby behaviour).
It would be nice if it was possible to only make these changes when working within the spec, but this would require injecting Async::HTTP::Client
everywhere which is probably impossible in general. The only way I could see that working is some kind of feature within Ruby like refinements, which basically lets you override globals/constants on a per-block basis.
That being said, it would be nice if we split the WebMock support for Async into two parts - those that are fairly pure and require injection, and those which just do the constant replacement. That way, engineer's writing tests can decide for themselves what approach works best for them, and the former approach, I'd be happy to completely support within Async::HTTP::Mock
.
I realised a slightly better implementation might be:
endpoint = Async::HTTP::Endpoint.parse("http://localhost", Async::IO::Endpoint.unix("server.ipc"))
Using a unix pipe avoids all the in-process queues and behaves more like a standard I/O.
This provides some basic building blocks for mocking up
Async::HTTP::Client
in the same process.https://github.com/socketry/async-http/issues/35