I want to write tests for a web client. As it was recommended by the aiohttp library author, I set up a local test server. This setup (boiling down this example) works well with plain http/port 80.
import ssl
import socket as skt
import unittest as ut
import aiohttp as ah
import aiohttp.web as ahweb
import aiohttp.test_utils as ahtest
EXPECTED_SERVER_URL = 'https://anywhere.com'
async def function_to_test(client_session):
async with client_session.get(EXPECTED_SERVER_URL) as response:
return await response.json()
class ResolverMock(ah.resolver.AbstractResolver):
def __init__(self, server_port, host, request_port):
self.__server_port = server_port
self.__host = host.rstrip('/').rpartition('://')[-1]
self.__request_port = request_port
async def resolve(self, host, request_port=0, family=skt.AF_INET):
if host != self.__host or request_port != self.__request_port:
raise OSError('No test server known for %s' % host)
return [dict(hostname=host, host='127.0.0.1', port=self.__server_port,
family=skt.AF_INET, proto=0, flags=skt.AI_NUMERICHOST)]
async def close(self) -> None:
pass
class ServerMock(ahtest.RawTestServer):
def __init__(self, **kwargs):
super().__init__(self.__handle_request, **kwargs)
async def __handle_request(self, _request):
return ahweb.json_response({})
class Fetch(ut.IsolatedAsyncioTestCase):
async def test_request_server(self):
async with ServerMock(port=443) as server_mock:
ssl_ctx = False
resolver = ResolverMock(server_port=server_mock.port, host=EXPECTED_SERVER_URL, request_port=443)
connector = ah.TCPConnector(resolver=resolver, ssl=ssl_ctx, use_dns_cache=False)
async with ah.ClientSession(connector=connector, trust_env=True) as session:
response = await function_to_test(session)
self.assertEqual(response, {})
if __name__ == '__main__':
ut.main()
But it fails for https/port 443 with
aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host anywhere.com:443 ssl:default [[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1108)]
Using a non_validating ssl context did not change anything:
ssl_ctx = ssl.create_default_context()
ssl_ctx.check_hostname = False
ssl_ctx.verify_mode = ssl.CERT_NONE
I have no idea how I could set up a compatible protocol or whatever (I am far away from being an ssl expert) on the test server. What do I miss? How can I make this work for https?