Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/peopledoc/mock-services
Mock services
https://github.com/peopledoc/mock-services
approved-public ghec-mig-migrated
Last synced: 17 days ago
JSON representation
Mock services
- Host: GitHub
- URL: https://github.com/peopledoc/mock-services
- Owner: peopledoc
- License: mit
- Created: 2015-12-07T09:33:04.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2022-01-18T14:32:44.000Z (almost 3 years ago)
- Last Synced: 2024-12-03T23:47:58.370Z (about 1 month ago)
- Topics: approved-public, ghec-mig-migrated
- Language: Python
- Homepage:
- Size: 49.8 KB
- Stars: 5
- Watchers: 9
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.rst
- Changelog: CHANGELOG
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
=============
Mock services
=============.. image:: https://circleci.com/gh/novafloss/mock-services.svg?style=shield
:target: https://circleci.com/gh/novafloss/mock-services
:alt: We are under CI!!Aims to provide an easy way to mock an entire service API based on
`requests-mock`_ and a simple dict definition of a service. The idea is to mock
everything at start according given rules. Then `mock-services`_ allows to
*start/stop* http mock locally.During our session we can:
- add rules
- permit external calls
- stop mocking
- reset rules
- restart mocking
- etc.Mock endpoints explicitly
=========================*Note:* rules urls must be regex. They always will be compiled before updating
the main `requests-mock`_ urls registry.Let's mock our favorite search engine::
>>> def fake_duckduckgo_cb(request):
... return 200, {}, 'Coincoin!'>>> rules = [
... {
... 'text': fake_duckduckgo_cb,
... 'headers': {'Content-Type': 'text/html'},
... 'method': 'GET',
... 'url': r'^https://duckduckgo.com/\?q='
... },
... ]>>> from mock_services import update_http_rules
>>> update_http_rules(rules)>>> import requests
>>> requests.get('https://duckduckgo.com/?q=mock-services').content[:15]
''>>> from mock_services import start_http_mock
>>> start_http_mock()>>> requests.get('https://duckduckgo.com/?q=mock-services').content
'Coincoin!'When the http_mock is started if you try to call an external url, it should
fail::>>> requests.get('https://www.google.com/#q=mock-services')
...
ConnectionError: Connection refused: GET https://www.google.com/#q=mock-servicesThen you can allow external calls if needed::
>>> from mock_services import http_mock
>>> http_mock.set_allow_external(True)>>> requests.get('https://www.google.com/#q=mock-services').content[:15]
''At anytime you can stop the mocking as follow::
>>> from mock_services import stop_http_mock
>>> stop_http_mock()>>> requests.get('https://duckduckgo.com/?q=mock-services').content[:15]
''Or stop mocking during a function call::
>>> start_http_mock()
>>> @no_http_mock
... def please_do_not_mock_me():
... return requests.get('https://duckduckgo.com/?q=mock-services').content[:15] == '', 'mocked!'>>> please_do_not_mock_me
Or start mocking for another function call::
>>> stop_http_mock()
>>> @with_http_mock
... def please_mock_me():
... assert requests.get('https://duckduckgo.com/?q=mock-services').content == 'Coincoin', 'no mock!'>>> please_mock_me
Mock service easy
=================You can add REST rules with an explicit method. It will add rules as above and
automatically bind callbacks to fake a REST service.*Note:* *resource* and *id* regex options are mandatory in the rules urls.
Additionally, `mock_services`_ include `attrs`_ library. It can be use for
field validation as follow.This service mock will create, get, update and delete resources for you::
>>> import attr
>>> rest_rules = [
... {
... 'method': 'LIST',
... 'url': r'^http://my_fake_service/(?Papi)$'
... },
... {
... 'method': 'GET',
... 'url': r'^http://my_fake_service/(?Papi)/(?P\d+)$',
... },
... {
... 'method': 'GET',
... 'url': r'^http://my_fake_service/(?Papi)/(?P\d+)/(?Pdownload)$',
... },
... {
... 'method': 'POST',
... 'url': r'^http://my_fake_service/(?Papi)$',
... 'id_name': 'id',
... 'id_factory': int,
... 'attrs': {
... 'bar': attr.ib(),
... 'foo':attr.ib(default=True)
... }
... },
... {
... 'method': 'PATCH',
... 'url': r'^http://my_fake_service/(?Papi)/(?P\d+)$',
... },
... {
... 'method': 'DELETE',
... 'url': r'^http://my_fake_service/(?Papi)/(?P\d+)$'
... },
... ]>>> from mock_services import update_rest_rules
>>> update_rest_rules(rest_rules)>>> from mock_services import start_http_mock
>>> start_http_mock()>>> response = requests.get('http://my_fake_service/api')
>>> response.status_code
200
>>> response.json()
[]>>> response = requests.get('http://my_fake_service/api/1')
>>> response.status_code
404>>> import json
>>> response = requests.post('http://my_fake_service/api',
... data=json.dumps({}),
... headers={'content-type': 'application/json'})
>>> response.status_code
400>>> response = requests.post('http://my_fake_service/api',
... data=json.dumps({'bar': 'Python will save the world'}),
... headers={'content-type': 'application/json'})
>>> response.status_code
201
>>> response.json()
{
'id': 1,
'foo'; True,
'bar'; 'Python will save the world.'
}>>> response = requests.patch('http://my_fake_service/api/1',
... data=json.dumps({'bar': "Python will save the world. I don't know how. But it will."}),
... headers={'content-type': 'application/json'})
>>> response.status_code
200>>> response = requests.get('http://my_fake_service/api/1')
>>> response.status_code
200
>>> response.json()
{
'id': 1,
'foo'; True,
'bar'; "Python will save the world. I don't know how. But it will."
}>>> response = requests.delete('http://my_fake_service/api/1')
>>> response.status_code
204More validation
===============Is some cases you need to validate a resource against another. Then you can add
global validators per endpoint as follow::>>> from mock_services import storage
>>> from mock_services.service import ResourceContext
>>> from mock_services.exceptions import Http409>>> def duplicate_foo(request):
... data = json.loads(request.body)
... ctx = ResourceContext(hostname='my_fake_service', resource='api')
... if data['foo'] in [o['foo'] for o in storage.list(ctx)]:
... raise Http409>>> rest_rules_with_validators = [
... {
... 'method': 'POST',
... 'url': r'^http://my_fake_service/(?Papi)$',
... 'validators': [
... duplicate_foo,
... ],
... },
... ]>>> response = requests.post('http://my_fake_service/api',
... data=json.dumps({'foo': 'bar'}),
... headers={'content-type': 'application/json'})
>>> response.status_code
201>>> response = requests.post('http://my_fake_service/api',
... data=json.dumps({'foo': 'bar'}),
... headers={'content-type': 'application/json'})
>>> response.status_code
409Have fun in testing external APIs ;)
.. _`attrs`: https://github.com/hynek/attrs
.. _`requests-mock`: https://github.com/openstack/requests-mock
.. _`mock-services`: https://github.com/novafloss/mock-services