Skip to content

Commit 8eae0c7

Browse files
authored
aiohttp reuses SSLContext instances created at import-time (#259)
* `aiohttp` reuses SSLContext instances created at import-time.
1 parent d0b43a1 commit 8eae0c7

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

mocket/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
from .async_mocket import async_mocketize
2-
from .mocket import Mocket, MocketEntry, Mocketizer, mocketize
2+
from .mocket import FakeSSLContext, Mocket, MocketEntry, Mocketizer, mocketize
33

4-
__all__ = ("async_mocketize", "mocketize", "Mocket", "MocketEntry", "Mocketizer")
4+
__all__ = (
5+
"async_mocketize",
6+
"mocketize",
7+
"Mocket",
8+
"MocketEntry",
9+
"Mocketizer",
10+
"FakeSSLContext",
11+
)
512

613
__version__ = "3.13.1"

mocket/plugins/aiohttp_connector.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import contextlib
2+
3+
from mocket import FakeSSLContext
4+
5+
with contextlib.suppress(ModuleNotFoundError):
6+
from aiohttp import ClientRequest
7+
from aiohttp.connector import TCPConnector
8+
9+
class MocketTCPConnector(TCPConnector):
10+
"""
11+
`aiohttp` reuses SSLContext instances created at import-time,
12+
making it more difficult for Mocket to do its job.
13+
This is an attempt to make things smoother, at the cost of
14+
slightly patching the `ClientSession` while testing.
15+
"""
16+
17+
def _get_ssl_context(self, req: ClientRequest) -> FakeSSLContext:
18+
return FakeSSLContext()

tests/test_asyncio.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import socket
55
import tempfile
66

7+
import aiohttp
78
import pytest
89

910
from mocket import Mocketizer, async_mocketize
1011
from mocket.mockhttp import Entry
12+
from mocket.plugins.aiohttp_connector import MocketTCPConnector
1113

1214

1315
def test_asyncio_record_replay(event_loop):
@@ -45,7 +47,10 @@ async def test_asyncio_connection():
4547
@pytest.mark.asyncio
4648
@async_mocketize
4749
async def test_aiohttp():
48-
import aiohttp
50+
"""
51+
The alternative to using the custom `connector` would be importing
52+
`aiohttp` when Mocket is already in control (inside the decorated test).
53+
"""
4954

5055
url = "https://bar.foo/"
5156
data = {"message": "Hello"}
@@ -58,7 +63,7 @@ async def test_aiohttp():
5863
)
5964

6065
async with aiohttp.ClientSession(
61-
timeout=aiohttp.ClientTimeout(total=3)
66+
timeout=aiohttp.ClientTimeout(total=3), connector=MocketTCPConnector()
6267
) as session, session.get(url) as response:
6368
response = await response.json()
6469
assert response == data

0 commit comments

Comments
 (0)