Skip to main content

HTTP traffic mocking and expectations made easy

Project description

modern-pook

Build Status

This is somewhat of a verbatim copy of h2non/pook, but it doesn’t support python 2, or older versions of python 3. Use this one if you need python 3.11 support.

Versatile, expressive and hackable utility library for HTTP traffic mocking and expectations made easy in Python. Heavily inspired by gock.

To get started, see the documentation, how it works, FAQ or examples.

Features

  • Simple, expressive and fluent API.

  • Provides both Pythonic and chainable DSL API styles.

  • Full-featured HTTP response definitions and expectations.

  • Matches any HTTP protocol primitive (URL, method, query params, headers, body…).

  • Full regular expressions capable mock expectations matching.

  • Supports most popular HTTP clients via interceptor adapters.

  • Configurable volatile, persistent or TTL limited mocks.

  • Works with any testing framework/engine (unittest, pytest…).

  • First-class JSON & XML support matching and responses.

  • Supports JSON Schema body matching.

  • Works in both runtime and testing environments.

  • Can be used as decorator and/or via context managers.

  • Supports real networking mode with optional traffic filtering.

  • Map/filter mocks easily for generic or custom mock expectations.

  • Custom user-defined mock matcher functions.

  • Simulated raised error exceptions.

  • Network delay simulation (only available for aiohttp).

  • Pluggable and hackable API.

  • Customizable HTTP traffic mock interceptor engine.

  • Supports third-party mocking engines, such as mocket.

  • Fits good for painless test doubles.

  • Does not support WebSocket traffic mocking.

  • Works with +3.8 (including PyPy).

  • Dependency-less: just 2 small dependencies for JSONSchema and XML tree comparison.

Supported HTTP clients

pook can work with multiple mock engines, however it provides a built-in one by default, which currently supports traffic mocking in the following HTTP clients:

More HTTP clients can be supported progressively.

Note: only recent HTTP client package versions were tested.

Installation

Using pip package manager (requires pip 1.8+):

pip install --upgrade modern-pook

Or install the latest sources from Github:

pip install -e git+git://github.com/odarbelaeze/pook.git#egg=pook

Getting started

See ReadTheDocs documentation:

Documentation Status

API

See annotated API reference documention.

Examples

See examples documentation for full featured code and use case examples.

Basic mocking:

import pook
import requests

@pook.on
def test_my_api():
    mock = pook.get('http://twitter.com/api/1/foobar', reply=404, response_json={'error': 'not found'})

    resp = requests.get('http://twitter.com/api/1/foobar')
    assert resp.status_code == 404
    assert resp.json() == {"error": "not found"}
    assert mock.calls == 1

Using the chainable API DSL:

import pook
import requests

@pook.on
def test_my_api():
    mock = (pook.get('http://twitter.com/api/1/foobar')
              .reply(404)
              .json({'error': 'not found'}))

    resp = requests.get('http://twitter.com/api/1/foobar')
    assert resp.json() == {"error": "not found"}
    assert mock.calls == 1

Using the decorator:

import pook
import requests

@pook.get('http://httpbin.org/status/500', reply=204)
@pook.get('http://httpbin.org/status/400', reply=200)
def fetch(url):
    return requests.get(url)

res = fetch('http://httpbin.org/status/400')
print('#1 status:', res.status_code)

res = fetch('http://httpbin.org/status/500')
print('#2 status:', res.status_code)

Simple unittest integration:

import pook
import unittest
import requests


class TestUnitTestEngine(unittest.TestCase):

    @pook.on
    def test_request(self):
        pook.get('server.com/foo').reply(204)
        res = requests.get('http://server.com/foo')
        self.assertEqual(res.status_code, 204)

    def test_request_with_context_manager(self):
        with pook.use():
            pook.get('server.com/bar', reply=204)
            res = requests.get('http://server.com/bar')
            self.assertEqual(res.status_code, 204)

Using the context manager for isolated HTTP traffic interception blocks:

import pook
import requests

# Enable HTTP traffic interceptor
with pook.use():
    pook.get('http://httpbin.org/status/500', reply=204)

    res = requests.get('http://httpbin.org/status/500')
    print('#1 status:', res.status_code)

# Interception-free HTTP traffic
res = requests.get('http://httpbin.org/status/200')
print('#2 status:', res.status_code)

Example using mocket Python library as underlying mock engine:

import pook
import requests
from mocket.plugins.pook_mock_engine import MocketEngine

# Use mocket library as underlying mock engine
pook.set_mock_engine(MocketEngine)

# Explicitly enable pook HTTP mocking (optional)
pook.on()

# Target server URL to mock out
url = 'http://twitter.com/api/1/foobar'

# Define your mock
mock = pook.get(url,
                reply=404, times=2,
                headers={'content-type': 'application/json'},
                response_json={'error': 'foo'})

# Run first HTTP request
requests.get(url)
assert mock.calls == 1

# Run second HTTP request
res = requests.get(url)
assert mock.calls == 2

# Assert response data
assert res.status_code == 404
assert res.json() == {'error': 'foo'}

# Explicitly disable pook (optional)
pook.off()

Development

Clone the repository:

git clone git@github.com:odarbelaeze/pook.git

Install dependencies:

pip install -r requirements.txt -r requirements-dev.txt

Install Python dependencies:

make install

Lint code:

make lint

Run tests:

make test

Generate documentation:

make htmldocs

License

MIT - Tomas Aparicio

v2.0.0 / 2022-12-21

  • Drop support for python 2.x, and python < 3.8.

  • Fix support for python 3.11.

v1.0.2 / 2021-09-10

  • fix(urllib3): interceptor is never really disabled (#68)

  • Closes #75 Re consider @fluent decorator (#76)

  • fix(#69): use match keyword in pytest.raises

  • fix(History): invalid rst syntax

v1.0.1 / 2020-03-24

  • fix(aiohttp): compatible with non aiohttp projects (#67)

  • feat(History): add release changes

v1.0.0 / 2020-03-18

  • fix(aiohttp): use latest version, allow Python 3.5+ for async http client

v0.2.8 / 2019-10-31

  • fix collections import warning (#61)

v0.2.7 / 2019-10-21

  • fix collections import warning (#61)

v0.2.6 / 2019-02-01

  • Add mock.reply(new_response=True) to reset response definition object

v0.2.5 / 2017-10-19

  • refactor(setup): remove extra install dependency

  • Fix py27 compatibility (#49)

  • Add activate_async decorator (#48)

  • fix typo in pook.mock.Mock.ismatched.__doc__ (#47)

  • fix README example (#46)

v0.2.4 / 2017-10-03

  • fix(#45): regex URL issue

  • fix(travis): allow failures in pypy

  • feat(docs): add sponsor banner

  • refactor(History): normalize style

v0.2.3 / 2017-04-28

  • feat(docs): add supported version for aiohttp

  • Merge branch ‘master’ of https://github.com/h2non/pook

  • fix(api): export missing symbol “disable_network”

  • Update README.rst (#43)

v0.2.2 / 2017-04-03

  • refactor(compare): disable maxDiff length limit while comparing values

v0.2.1 / 2017-03-25

  • fix(engine): enable new mock engine on register if needed

  • fix(engine): remove activate argument before instantiating the Mock

v0.2.0 / 2017-03-18

  • refactor(engine): do not activate engine on mock declaration if not explicitly requested. This introduces a behavioral library change: you must explicitly use pook.on() to enable pook mock engine.

v0.1.14 / 2017-03-17

  • feat(docs): list supported HTTP client versions

  • fix(#41): disable mocks after decorator call invokation

  • feat(examples): add mock context manager example file

  • feat(#40): support context manager definitions

  • feat(#39): improve unmatched request output

  • feat(docs): add mocket example file

  • feat(#33): add mocket examples and documentation

v0.1.13 / 2017-01-29

  • fix(api): mock.calls property should be an int.

v0.1.12 / 2017-01-28

  • feat(#33): proxy mock definitions into mock.Request

  • refactor(api): pook.unmatched_requests() now returns a list instead of a lazy tuple.

v0.1.11 / 2017-01-14

  • refactor(query)

  • fix(#37): fix URL comparison

  • fix(#38): proper mock engine interface validation.

v0.1.10 / 2017-01-13

  • fix(#37): decode byte bodies

  • feat(setup.py): add author email

v0.1.9 / 2017-01-06

  • fix(Makefile): remove proper egg file

  • feat(package): add wheel package distribution support

  • feat(docs): add documentation links

v0.1.8 / 2016-12-24

  • fix(assertion): extract regex pattern only when required

  • feat(examples): add regular expression example

v0.1.7 / 2016-12-18

  • feat(#33): add support for user defined custom mock engine

v0.1.6 / 2016-12-14

  • fix(setup.py): force utf-8 encoding

  • feat(setup.py): add encoding header

  • feat(api): add debug mode

  • refactor(docs): minor enhancements

  • refactor(tests): update URL matcher test cases

  • refactor(docs): add note about HTTP clients and update features list

  • fix(setup.py): remove encoding param

  • fix(tests): use strict equality assertion

0.1.5 / 2016-12-12

  • fix(matchers): fix matching issue in URL.

  • refactor(assertion): regex expression based matching must be explicitly enabled.

  • feat(tests): add initial matchers tests.

0.1.4 / 2016-12-08

  • refactor(README): minor changes

  • fix(setup.py): lint error

  • fix(#32): use explicit encoding while reading files in setup.py

0.1.3 / 2016-12-08

  • fix(core): several bug fixes.

  • feat(core): add pending features and major refactors.

  • feat(matchers): use unittest.TestCase matching engine by default.

0.1.2 / 2016-12-01

  • fix(matchers): runtime missing variable.

0.1.1 / 2016-12-01

  • fix: Python 2 dictionary iteration syntax.

  • feat(docs): add more examples.

  • fix(matchers): better regular expression comparison support.

0.1.0 / 2016-11-30

  • First version (still beta)

0.1.0-rc.1 / 2016-11-27

  • First release candidate version (still beta)

Project details


Download files

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

Source Distribution

modern-pook-2.0.0.tar.gz (37.7 kB view details)

Uploaded Source

Built Distribution

modern_pook-2.0.0-py3-none-any.whl (53.5 kB view details)

Uploaded Python 3

File details

Details for the file modern-pook-2.0.0.tar.gz.

File metadata

  • Download URL: modern-pook-2.0.0.tar.gz
  • Upload date:
  • Size: 37.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.1

File hashes

Hashes for modern-pook-2.0.0.tar.gz
Algorithm Hash digest
SHA256 38fa79c42f83a53f07aa8b5b9d3d24aa5383ffe38830666ad4b15e5dcb1f5b2f
MD5 491ca19a5d546c42175695e3a22a4e16
BLAKE2b-256 fd5bd39166c0b409da04f6c54803928f93468f4904bfcc332bebb2b0d8bef77d

See more details on using hashes here.

File details

Details for the file modern_pook-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: modern_pook-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 53.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.1

File hashes

Hashes for modern_pook-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dadc5f5e18ba01b642caf3d67d4bc66442c18f534a1bbaa0723ae58057c3d81a
MD5 df87e639263a5e30249f9bc65dfd7c87
BLAKE2b-256 3f08d465ec4cf5c9552aada23c42904024ec09c8a679dbdf4fc29922adb2b604

See more details on using hashes here.

Supported by

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