123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- ===============================
- aioresponses
- ===============================
- .. image:: https://travis-ci.org/pnuckowski/aioresponses.svg?branch=master
- :target: https://travis-ci.org/pnuckowski/aioresponses
- .. image:: https://coveralls.io/repos/github/pnuckowski/aioresponses/badge.svg?branch=master
- :target: https://coveralls.io/github/pnuckowski/aioresponses?branch=master
- .. image:: https://landscape.io/github/pnuckowski/aioresponses/master/landscape.svg?style=flat
- :target: https://landscape.io/github/pnuckowski/aioresponses/master
- :alt: Code Health
- .. image:: https://pyup.io/repos/github/pnuckowski/aioresponses/shield.svg
- :target: https://pyup.io/repos/github/pnuckowski/aioresponses/
- :alt: Updates
- .. image:: https://img.shields.io/pypi/v/aioresponses.svg
- :target: https://pypi.python.org/pypi/aioresponses
- .. image:: https://readthedocs.org/projects/aioresponses/badge/?version=latest
- :target: https://aioresponses.readthedocs.io/en/latest/?badge=latest
- :alt: Documentation Status
- Aioresponses is a helper to mock/fake web requests in python aiohttp package.
- For *requests* module 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
- ----------
- .. code:: bash
- $ pip install aioresponses
- Supported versions
- ------------------
- - Python 3.7+
- - aiohttp>=3.3.0,<4.0.0
- Usage
- --------
- To mock out HTTP request use *aioresponses* as a method decorator or as a context manager.
- Response *status* code, *body*, *payload* (for json response) and *headers* can be mocked.
- Supported HTTP methods: **GET**, **POST**, **PUT**, **PATCH**, **DELETE** and **OPTIONS**.
- .. code:: python
- import aiohttp
- import asyncio
- from aioresponses import aioresponses
- @aioresponses()
- def test_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'))
- assert resp.status == 200
- mocked.assert_called_once_with('http://example.com')
- for convenience use *payload* argument to mock out json response. Example below.
- **as a context manager**
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import aioresponses
- def test_ctx():
- loop = asyncio.get_event_loop()
- session = aiohttp.ClientSession()
- with aioresponses() as m:
- 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())
- assert dict(foo='bar') == data
- m.assert_called_once_with('http://test.example.com')
- **aioresponses allows to mock out any HTTP headers**
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import aioresponses
- @aioresponses()
- def test_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 headers
- assert resp.headers['Connection'] == 'keep-alive'
- m.assert_called_once_with('http://example.com', method='POST')
- **allows to register different responses for the same url**
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import aioresponses
- @aioresponses()
- def test_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'))
- assert resp1.status == 500
- assert resp2.status == 200
- **Repeat response for the same url**
- E.g. for cases you want to test retrying mechanisms
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import aioresponses
- @aioresponses()
- def test_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 effect
- resp1 = loop.run_until_complete(session.get('http://example.com'))
- resp2 = loop.run_until_complete(session.get('http://example.com'))
- assert resp1.status == 500
- assert resp2.status == 500
- **match URLs with regular expressions**
- .. code:: python
- import asyncio
- import aiohttp
- import re
- from aioresponses import aioresponses
- @aioresponses()
- def test_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'))
- assert resp.status == 200
- **allows to make redirects responses**
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import aioresponses
- @aioresponses()
- def test_redirect_example(m):
- loop = asyncio.get_event_loop()
- session = aiohttp.ClientSession()
- # absolute urls are supported
- m.get(
- 'http://example.com/',
- headers={'Location': 'http://another.com/'},
- status=307
- )
- resp = loop.run_until_complete(
- session.get('http://example.com/', allow_redirects=True)
- )
- assert resp.url == 'http://another.com/'
- # and also relative
- m.get(
- 'http://example.com/',
- headers={'Location': '/test'},
- status=307
- )
- resp = loop.run_until_complete(
- session.get('http://example.com/', allow_redirects=True)
- )
- assert resp.url == 'http://example.com/test'
- **allows to passthrough to a specified list of servers**
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import aioresponses
- @aioresponses(passthrough=['http://backend'])
- def test_passthrough(m, test_client):
- session = aiohttp.ClientSession()
- # this will actually perform a request
- resp = loop.run_until_complete(session.get('http://backend/api'))
- **also you can passthrough all requests except specified by mocking object**
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import aioresponses
- @aioresponses(passthrough_unmatched=True)
- def test_passthrough_unmatched(m, test_client):
- url = 'https://httpbin.org/get'
- m.get(url, status=200)
- session = aiohttp.ClientSession()
- # this will actually perform a request
- resp = loop.run_until_complete(session.get('http://backend/api'))
- # this will not perform a request and resp2.status will return 200
- resp2 = loop.run_until_complete(session.get(url))
- **aioresponses allows to throw an exception**
- .. code:: python
- import asyncio
- from aiohttp import ClientSession
- from aiohttp.http_exceptions import HttpProcessingError
- from aioresponses import aioresponses
- @aioresponses()
- def test_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 responses**
- .. code:: python
- import asyncio
- import aiohttp
- from aioresponses import CallbackResult, aioresponses
- def callback(url, **kwargs):
- return CallbackResult(status=418)
- @aioresponses()
- def test_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'))
- assert resp.status == 418
- **aioresponses can be used in a pytest fixture**
- .. code:: python
- import pytest
- from aioresponses import aioresponses
- @pytest.fixture
- def mock_aioresponse():
- with aioresponses() as m:
- yield m
- Features
- --------
- * Easy to mock out HTTP requests made by *aiohttp.ClientSession*
- License
- -------
- * Free software: MIT license
- Credits
- -------
- This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.
- .. _Cookiecutter: https://github.com/audreyr/cookiecutter
- .. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
|