
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Socket Mock Framework - for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support
.. image:: https://github.com/mindflayer/python-mocket/actions/workflows/main.yml/badge.svg?branch=main :target: https://github.com/mindflayer/python-mocket/actions?query=workflow%3A%22Mocket%27s+CI%22
.. image:: https://codecov.io/github/mindflayer/python-mocket/graph/badge.svg?token=htRySebRBt :target: https://codecov.io/github/mindflayer/python-mocket
.. image:: https://app.codacy.com/project/badge/Grade/6327640518ce42adaf59368217028f14 :target: https://www.codacy.com/gh/mindflayer/python-mocket/dashboard
.. image:: https://img.shields.io/pypi/dm/mocket :target: https://pypistats.org/packages/mocket
.. image:: https://raw.githubusercontent.com/mindflayer/python-mocket/main/mocket.png :height: 256px :width: 256px :alt: Mocket logo :align: center
for all kinds of socket *animals*, web-clients included - with gevent/asyncio/SSL support
...and then MicroPython's urequests (mocket >= 3.9.1)
Mocket packages are available for openSUSE
, NixOS
, ALT Linux
, NetBSD
, and of course from PyPI
_.
.. _openSUSE
: https://software.opensuse.org/search?baseproject=ALL&q=mocket
.. _NixOS
: https://search.nixos.org/packages?query=mocket
.. _ALT Linux
: https://packages.altlinux.org/en/sisyphus/srpms/python3-module-mocket/
.. _NetBSD
: https://cdn.netbsd.org/pub/pkgsrc/current/pkgsrc/devel/py-mocket/index.html
.. _PyPI
: https://pypi.org/project/mocket/
Starting from 3.7.0, Mocket major version will follow the same numbering pattern as Python's and therefore indicate the most recent Python version that is supported.
FYI: the last version compatible with Python 2.7 is 3.9.4, bugfixing or backporting of features introduced after that release will only be available as commercial support.
Star the project on GitHub, Buy Me a Coffee clicking the button below or, even better, contribute with patches or documentation.
.. image:: https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png :target: https://www.buymeacoffee.com/mocket :alt: Buy Me A Coffee
Read the following blog posts if you want to have a big picture of what Mocket is capable of:
The starting point to understand how to use Mocket to write a custom mock is the following example:
As next step, you are invited to have a look at the implementation of both the mocks it provides:
Please also have a look at the huge test suite:
Using pip::
$ pip install mocket
Mocket uses xxhash when available instead of hashlib.md5 for creating hashes, you can install it as follows::
$ pip install mocket[speedups]
When opening an Issue, please add few lines of code as failing test, or -better- open its relative Pull request adding this test to our test suite.
Let's create a new virtualenv with all we need::
$ python3 -m venv example
$ source example/bin/activate
$ pip install pytest requests mocket
As second step, we create an example.py
file as the following one:
.. code-block:: python
import json
from mocket import mocketize
from mocket.mocks.mockhttp import Entry
import requests
import pytest
@pytest.fixture
def response():
return {
"integer": 1,
"string": "asd",
"boolean": False,
}
@mocketize # use its decorator
def test_json(response):
url_to_mock = 'https://testme.org/json'
Entry.single_register(
Entry.GET,
url_to_mock,
body=json.dumps(response),
headers={'content-type': 'application/json'}
)
mocked_response = requests.get(url_to_mock).json()
assert response == mocked_response
# OR use its context manager
from mocket import Mocketizer
def test_json_with_context_manager(response):
url_to_mock = 'https://testme.org/json'
Entry.single_register(
Entry.GET,
url_to_mock,
body=json.dumps(response),
headers={'content-type': 'application/json'}
)
with Mocketizer():
mocked_response = requests.get(url_to_mock).json()
assert response == mocked_response
Let's fire our example test::
$ py.test example.py
socket
?NEW!!! Sometimes you just want your tests to fail when they attempt to use the network.
.. code-block:: python
with Mocketizer(strict_mode=True):
with pytest.raises(StrictMocketException):
requests.get("https://duckduckgo.com/")
# OR
@mocketize(strict_mode=True)
def test_get():
with pytest.raises(StrictMocketException):
requests.get("https://duckduckgo.com/")
You can specify exceptions as a list of hosts or host-port pairs.
.. code-block:: python
with Mocketizer(strict_mode=True, strict_mode_allowed=["localhost", ("intake.ourmetrics.net", 443)]):
...
# OR
@mocketize(strict_mode=True, strict_mode_allowed=["localhost", ("intake.ourmetrics.net", 443)])
def test_get():
...
Add this instruction at the end of the test execution:
.. code-block:: python
Mocket.assert_fail_if_entries_not_served()
It's very important that we test non-happy paths.
.. code-block:: python
@mocketize
def test_raise_exception(self):
url = "http://github.com/fluidicon.png"
Entry.single_register(Entry.GET, url, exception=socket.error())
with self.assertRaises(requests.exceptions.ConnectionError):
requests.get(url)
You probably know what VCRpy is capable of, that's the mocket's way of achieving it:
.. code-block:: python
@mocketize(truesocket_recording_dir=tempfile.mkdtemp())
def test_truesendall_with_recording_https():
url = 'https://httpbin.org/ip'
requests.get(url, headers={"Accept": "application/json"})
resp = requests.get(url, headers={"Accept": "application/json"})
assert resp.status_code == 200
dump_filename = os.path.join(
Mocket.get_truesocket_recording_dir(),
Mocket.get_namespace() + '.json',
)
with io.open(dump_filename) as f:
response = json.load(f)
assert len(response['httpbin.org']['443'].keys()) == 1
Mocket HTTP mock can work as HTTPretty replacement for many different use cases. Two main features are missing:
Two features which are against the Zen of Python, at least imho (mindflayer), but of course I am open to call it into question.
Example:
.. code-block:: python
import json
import aiohttp
import asyncio
from unittest import TestCase
from mocket.plugins.httpretty import httpretty, httprettified
class AioHttpEntryTestCase(TestCase):
@httprettified
def test_https_session(self):
url = 'https://httpbin.org/ip'
httpretty.register_uri(
httpretty.GET,
url,
body=json.dumps(dict(origin='127.0.0.1')),
)
async def main(l):
async with aiohttp.ClientSession(
loop=l, timeout=aiohttp.ClientTimeout(total=3)
) as session:
async with session.get(url) as get_response:
assert get_response.status == 200
assert await get_response.text() == '{"origin": "127.0.0.1"}'
loop = asyncio.new_event_loop()
loop.set_debug(True)
loop.run_until_complete(main(loop))
Using Mocket with asyncio based clients::
$ pip install aiohttp
Example:
.. code-block:: python
# `aiohttp` creates SSLContext instances at import-time
# that's why Mocket would get stuck when dealing with HTTP
# Importing the module while Mocket is in control (inside a
# decorated test function or using its context manager would
# be enough for making it work), the alternative is using a
# custom TCPConnector which always return a FakeSSLContext
# from Mocket like this example is showing.
import aiohttp
import pytest
from mocket import async_mocketize
from mocket.mocks.mockhttp import Entry
from mocket.plugins.aiohttp_connector import MocketTCPConnector
@pytest.mark.asyncio
@async_mocketize
async def test_aiohttp():
"""
The alternative to using the custom `connector` would be importing
`aiohttp` when Mocket is already in control (inside the decorated test).
"""
url = "https://bar.foo/"
data = {"message": "Hello"}
Entry.single_register(
Entry.GET,
url,
body=json.dumps(data),
headers={"content-type": "application/json"},
)
async with aiohttp.ClientSession(
timeout=aiohttp.ClientTimeout(total=3), connector=MocketTCPConnector()
) as session, session.get(url) as response:
response = await response.json()
assert response == data
Using Mocket as pook_ engine::
$ pip install mocket[pook]
.. _pook: https://pypi.python.org/pypi/pook
Example:
.. code-block:: python
import pook
from mocket.plugins.pook_mock_engine import MocketEngine
pook.set_mock_engine(MocketEngine)
pook.on()
url = 'http://twitter.com/api/1/foobar'
status = 404
response_json = {'error': 'foo'}
mock = pook.get(
url,
headers={'content-type': 'application/json'},
reply=status,
response_json=response_json,
)
mock.persist()
requests.get(url)
assert mock.calls == 1
resp = requests.get(url)
assert resp.status_code == status
assert resp.json() == response_json
assert mock.calls == 2
EuroPython 2013, Florence
FAQs
Socket Mock Framework - for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support
We found that mocket demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.