Package: aioresponses
Aioresponses is a helper to mock/fake web requests in python aiohttp package.Forrequestsmodule there are a lot of packages that help us with testing (eg.httpretty,responses,requests-mock).When it comes to testing asynchronous HTTP requests it is a bit harder (at least at the beginning).
The purpose of this package is to provide an easy way to test asynchronous HTTP requests.Installing$pipinstallaioresponsesSupported versionsPython 3.7+aiohttp>=3.3.0,<4.0.0UsageTo mock out HTTP request useaioresponsesas a method decorator or as a context manager.Responsestatuscode,body,payload(for json response) andheaderscan be mocked.Supported HTTP methods:GET,POST,PUT,PATCH,DELETEandOPTIONS.importaiohttpimportasynciofromaioresponsesimportaioresponses@aioresponses()deftest_request(mocked):loop=asyncio.get_event_loop()mocked.get('http://example.com',status=200,body='test')session=aiohttp.ClientSession()resp=loop.run_until_complete(session.get('http://example.com'))assertresp.status==200mocked.assert_called_once_with('http://example.com')for convenience usepayloadargument to mock out json response. Example below.as a context managerimportasyncioimportaiohttpfromaioresponsesimportaioresponsesdeftest_ctx():loop=asyncio.get_event_loop()session=aiohttp.ClientSession()withaioresponses()asm:m.get('http://test.example.com',payload=dict(foo='bar'))resp=loop.run_until_complete(session.get('http://test.example.com'))data=loop.run_until_complete(resp.json())assertdict(foo='bar')==datam.assert_called_once_with('http://test.example.com')aioresponses allows to mock out any HTTP headersimportasyncioimportaiohttpfromaioresponsesimportaioresponses@aioresponses()deftest_http_headers(m):loop=asyncio.get_event_loop()session=aiohttp.ClientSession()m.post('http://example.com',payload=dict(),headers=dict(connection='keep-alive'),)resp=loop.run_until_complete(session.post('http://example.com'))# note that we pass 'connection' but get 'Connection' (capitalized)# under the neath `multidict` is used to work with HTTP headersassertresp.headers['Connection']=='keep-alive'm.assert_called_once_with('http://example.com',method='POST')allows to register different responses for the same urlimportasyncioimportaiohttpfromaioresponsesimportaioresponses@aioresponses()deftest_multiple_responses(m):loop=asyncio.get_event_loop()session=aiohttp.ClientSession()m.get('http://example.com',status=500)m.get('http://example.com',status=200)resp1=loop.run_until_complete(session.get('http://example.com'))resp2=loop.run_until_complete(session.get('http://example.com'))assertresp1.status==500assertresp2.status==200Repeat response for the same urlE.g. for cases you want to test retrying mechanismsimportasyncioimportaiohttpfromaioresponsesimportaioresponses@aioresponses()deftest_multiple_responses(m):loop=asyncio.get_event_loop()session=aiohttp.ClientSession()m.get('http://example.com',status=500,repeat=True)m.get('http://example.com',status=200)# will not take effectresp1=loop.run_until_complete(session.get('http://example.com'))resp2=loop.run_until_complete(session.get('http://example.com'))assertresp1.status==500assertresp2.status==500match URLs with regular expressionsimportasyncioimportaiohttpimportrefromaioresponsesimportaioresponses@aioresponses()deftest_regexp_example(m):loop=asyncio.get_event_loop()session=aiohttp.ClientSession()pattern=re.compile(r'^http://example\.com/api\?foo=.*$')m.get(pattern,status=200)resp=loop.run_until_complete(session.get('http://example.com/api?foo=bar'))assertresp.status==200allows to make redirects responsesimportasyncioimportaiohttpfromaioresponsesimportaioresponses@aioresponses()deftest_redirect_example(m):loop=asyncio.get_event_loop()session=aiohttp.ClientSession()# absolute urls are supportedm.get('http://example.com/',headers={'Location':'http://another.com/'},status=307)resp=loop.run_until_complete(session.get('http://example.com/',allow_redirects=True))assertresp.url=='http://another.com/'# and also relativem.get('http://example.com/',headers={'Location':'/test'},status=307)resp=loop.run_until_complete(session.get('http://example.com/',allow_redirects=True))assertresp.url=='http://example.com/test'allows to passthrough to a specified list of serversimportasyncioimportaiohttpfromaioresponsesimportaioresponses@aioresponses(passthrough=['http://backend'])deftest_passthrough(m,test_client):session=aiohttp.ClientSession()# this will actually perform a requestresp=loop.run_until_complete(session.get('http://backend/api'))aioresponses allows to throw an exceptionimportasynciofromaiohttpimportClientSessionfromaiohttp.http_exceptionsimportHttpProcessingErrorfromaioresponsesimportaioresponses@aioresponses()deftest_how_to_throw_an_exception(m,test_client):loop=asyncio.get_event_loop()session=ClientSession()m.get('http://example.com/api',exception=HttpProcessingError('test'))# calling# loop.run_until_complete(session.get('http://example.com/api'))# will throw an exception.aioresponses allows to use callbacks to provide dynamic responsesimportasyncioimportaiohttpfromaioresponsesimportCallbackResult,aioresponsesdefcallback(url,**kwargs):returnCallbackResult(status=418)@aioresponses()deftest_callback(m,test_client):loop=asyncio.get_event_loop()session=ClientSession()m.get('http://example.com',callback=callback)resp=loop.run_until_complete(session.get('http://example.com'))assertresp.status==418aioresponses can be used in a pytest fixtureimportpytestfromaioresponsesimportaioresponses@pytest.fixturedefmock_aioresponse():withaioresponses()asm:yieldmFeaturesEasy to mock out HTTP requests made byaiohttp.ClientSessionLicenseFree software: MIT licenseCreditsThis package was created withCookiecutterand theaudreyr/cookiecutter-pypackageproject template.