Skip to main content

Socket Mock Framework - for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support

Project description

https://travis-ci.org/mindflayer/python-mocket.svg?branch=master https://coveralls.io/repos/github/mindflayer/python-mocket/badge.svg?branch=master Code Climate Requirements Status

A socket mock framework

for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support

Versioning

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.

Support it

Star the project on GitHub, Buy Me a Coffee or, even better, contribute with patches or documentation.

Buy Me A Coffee

How to use it

Read these three 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 both the implementation of the two mocks it provides:

Please also have a look at the huge test suite:

Installation

Using pip:

$ pip install mocket

Speedups

Mocket uses xxhash when available instead of hashlib.md5 for creating hashes, you can install it as follows:

$ pip install mocket[speedups]

Issues

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.

Quick example of its HTTP mock

Let’s create a new virtualenv with all we need:

$ virtualenv example
$ source example/bin/activate
$ pip install pytest requests mocket

As second step, we create an example.py file as the following one:

import json

from mocket import mocketize
from mocket.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

HTTPretty compatibility layer

Mocket HTTP mock can work as HTTPretty replacement for many different use cases. Two main features are missing:

  • URL entries containing regular expressions;

  • response body from functions.

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:

import json

import aiohttp
import asyncio
import async_timeout
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) as session:
                with async_timeout.timeout(3):
                    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.get_event_loop()
        loop.set_debug(True)
        loop.run_until_complete(main(loop))

What about the other socket animals?

Using Mocket with asyncio based clients:

$ pip install aiohttp

Example:

class AioHttpEntryTestCase(TestCase):
    @mocketize
    def test_http_session(self):
        url = 'http://httpbin.org/ip'
        body = "asd" * 100
        Entry.single_register(Entry.GET, url, body=body, status=404)
        Entry.single_register(Entry.POST, url, body=body*2, status=201)

        async def main(l):
            async with aiohttp.ClientSession(loop=l) as session:
                with async_timeout.timeout(3):
                    async with session.get(url) as get_response:
                        assert get_response.status == 404
                        assert await get_response.text() == body

                with async_timeout.timeout(3):
                    async with session.post(url, data=body * 6) as post_response:
                        assert post_response.status == 201
                        assert await post_response.text() == body * 2

        loop = asyncio.get_event_loop()
        loop.run_until_complete(main(loop))

Works well with others

Using Mocket as pook engine:

$ pip install mocket[pook]

Example:

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

First appearance

EuroPython 2013, Florence

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mocket-3.8.3.tar.gz (71.9 kB view details)

Uploaded Source

File details

Details for the file mocket-3.8.3.tar.gz.

File metadata

  • Download URL: mocket-3.8.3.tar.gz
  • Upload date:
  • Size: 71.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.7.5

File hashes

Hashes for mocket-3.8.3.tar.gz
Algorithm Hash digest
SHA256 7766b2abff24413d7ec24894a589eddaec08e504166903a9f920c863d2f3c1e4
MD5 5047872fd1d263ca004dc671e4b11d0b
BLAKE2b-256 a2bb5ba5685ec930ef52c471d686ccb5566af0f2430a8ae2525b4efd5dff2251

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page