gabrielfalcao / HTTPretty

Intercept HTTP requests at the Python socket level. Fakes the whole socket module

Home Page:https://httpretty.readthedocs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

can not mock httpx

elonzh opened this issue · comments

HTTPretty is an awesome testing tool but it doesn't support mock httpx. Maybe we should consider supporting httpx?

demo code:

import httpretty
import httpx


def test_one():
    httpretty.enable()  # enable HTTPretty so that it will monkey patch the socket module
    httpretty.register_uri(httpretty.GET, "http://yipit.com/",
                           body="Find the best daily deals")

    response = httpx.get('http://yipit.com')

    assert response.text == "Find the best daily deals"

    httpretty.disable()  # disable afterwards, so that you will have no problems in code that uses that socket module
    httpretty.reset()  # reset HTTPretty state (clean up registered urls and request history)


if __name__ == '__main__':
    test_one()

output:

Traceback (most recent call last):
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_exceptions.py", line 326, in map_exceptions
    yield
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_client.py", line 861, in _send_single_request
    (status_code, headers, stream, ext) = transport.request(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpcore/_sync/connection_pool.py", line 218, in request
    response = connection.request(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpcore/_sync/connection.py", line 106, in request
    return self.connection.request(method, url, headers, stream, ext)
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 65, in request
    self._send_request(method, url, headers, timeout)
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 100, in _send_request
    self._send_event(event, timeout)
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpcore/_sync/http11.py", line 124, in _send_event
    self.socket.write(bytes_to_send, timeout)
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpcore/_backends/sync.py", line 73, in write
    data = data[n:]
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
    raise to_exc(exc) from None
httpcore.WriteError: [Errno 32] Broken pipe

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "./test.py", line 19, in <module>
    test_one()
  File "./test.py", line 10, in test_one
    response = httpx.get('http://yipit.com')
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_api.py", line 181, in get
    return request(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_api.py", line 93, in request
    return client.request(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_client.py", line 733, in request
    return self.send(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_client.py", line 767, in send
    response = self._send_handling_auth(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_client.py", line 805, in _send_handling_auth
    response = self._send_handling_redirects(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_client.py", line 837, in _send_handling_redirects
    response = self._send_single_request(request, timeout)
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_client.py", line 861, in _send_single_request
    (status_code, headers, stream, ext) = transport.request(
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/home/elonzh/miniconda/envs/unob/lib/python3.8/site-packages/httpx/_exceptions.py", line 343, in map_exceptions
    raise mapped_exc(message, **kwargs) from exc  # type: ignore
httpx.WriteError: [Errno 32] Broken pipe

For now, you could consider https://github.com/lundberg/respx which seems like the recommended way of mocking httpx.

I know that, but I prefer HTTPretty because it is more generic like vcrpy

Thanks for the report @elonzh I'll work on this soon.