Skip to content

Commit 3cb2a3a

Browse files
authored
Support for calls made by fastapi (#188)
* Introduce a `socket.socketpair()` function that acts as the real one
1 parent 2ec367e commit 3cb2a3a

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ build = "*"
2929
wheel = "*"
3030
twine = "*"
3131
anaconda-client = "*"
32+
fastapi = "*"
3233

3334
[requires]
3435
python_version = "3"

mocket/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
__all__ = ("async_mocketize", "mocketize", "Mocket", "MocketEntry", "Mocketizer")
55

6-
__version__ = "3.10.7"
6+
__version__ = "3.10.8"

mocket/mocket.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
true_gethostbyname = socket.gethostbyname
5252
true_gethostname = socket.gethostname
5353
true_getaddrinfo = socket.getaddrinfo
54+
true_socketpair = socket.socketpair
5455
true_ssl_wrap_socket = ssl.wrap_socket
5556
true_ssl_socket = ssl.SSLSocket
5657
true_ssl_context = ssl.SSLContext
@@ -136,6 +137,13 @@ def create_connection(address, timeout=None, source_address=None):
136137
return s
137138

138139

140+
def socketpair():
141+
"""Returns a real socketpair() used by asyncio loop for supporting calls made by fastapi and similar services."""
142+
import _socket
143+
144+
return _socket.socketpair()
145+
146+
139147
def _hash_request(h, req):
140148
return h(encode_to_bytes("".join(sorted(req.split("\r\n"))))).hexdigest()
141149

@@ -488,6 +496,7 @@ def enable(namespace=None, truesocket_recording_dir=None):
488496
] = lambda host, port, family=None, socktype=None, proto=None, flags=None: [
489497
(2, 1, 6, "", (host, port))
490498
]
499+
socket.socketpair = socket.__dict__["socketpair"] = socketpair
491500
ssl.wrap_socket = ssl.__dict__["wrap_socket"] = FakeSSLContext.wrap_socket
492501
ssl.SSLContext = ssl.__dict__["SSLContext"] = FakeSSLContext
493502
socket.inet_pton = socket.__dict__["inet_pton"] = lambda family, ip: byte_type(
@@ -520,6 +529,7 @@ def disable():
520529
socket.gethostname = socket.__dict__["gethostname"] = true_gethostname
521530
socket.gethostbyname = socket.__dict__["gethostbyname"] = true_gethostbyname
522531
socket.getaddrinfo = socket.__dict__["getaddrinfo"] = true_getaddrinfo
532+
socket.socketpair = socket.__dict__["socketpair"] = true_socketpair
523533
ssl.wrap_socket = ssl.__dict__["wrap_socket"] = true_ssl_wrap_socket
524534
ssl.SSLContext = ssl.__dict__["SSLContext"] = true_ssl_context
525535
socket.inet_pton = socket.__dict__["inet_pton"] = true_inet_pton

tests/tests37/test_httpx.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import httpx
44
import pytest
5+
from fastapi import FastAPI
6+
from fastapi.testclient import TestClient
57

6-
from mocket import Mocketizer, async_mocketize
8+
from mocket import Mocketizer, async_mocketize, mocketize
79
from mocket.mockhttp import Entry
810

911

@@ -48,3 +50,28 @@ async def test_httpx_fixture(httpx_client):
4850
response = await client.get(url)
4951

5052
assert response.json() == data
53+
54+
55+
def create_app() -> FastAPI:
56+
app = FastAPI()
57+
58+
@app.get("/")
59+
async def read_main() -> dict:
60+
async with httpx.AsyncClient() as client:
61+
r = await client.get("https://example.org/")
62+
return r.json()
63+
64+
return app
65+
66+
67+
@mocketize
68+
def test_call_from_fastapi() -> None:
69+
app = create_app()
70+
client = TestClient(app)
71+
72+
Entry.single_register(Entry.GET, "https://example.org/", body='{"id": 1}')
73+
74+
response = client.get("/")
75+
76+
assert response.status_code == 200
77+
assert response.json() == {"id": 1}

0 commit comments

Comments
 (0)