Skip to main content

Modern mocking library for Python.

Project description

mimid

Build Status Coverage Status License Version Python versions Code style: black

Modern mocking library for Python.

⚠️ This project is under heavy development, API could be unstable.

Installation

To install mimid, simply use pip:

$ pip install mimid

Quick start

from mimid import mock, every, verify, any, gt

def add(a: int, b: int) -> int:
    return a + b

def test_add():
    add_mock = mock(add)
    every(add_mock).returns(5)    

    result = add_mock(2, 2)

    assert result == 5
    verify(add_mock).with_args(any(), gt(0)).called(times=1)

Features

Mimid supports following features:

  • easy mock behaviour configuration and verification
  • works with classes and plain functions
  • fully type hinted - it works with IDE's and type checkers
  • clean API, without too much magic

Why not mock?

Python built-in mock module is an awesome tool. It's a first choice if you want to mock something in your tests.

However it has a few disadvantages:

  • it doesn't work well with modern IDEs (e.g. auto completion) and type checkers
  • it's difficult to define different behaviours for different cases
  • it allows too much freedom, you can do anything with your mock object, even if you didn't define any behaviour

Inspiration

Mimid is highly inspired by mocking frameworks from a JVM world, like mockito or mockk.

Usage

There are 3 simple steps in the mimid mocking workflow:

  1. Creation
  2. Configuration
  3. Verification

Additionally you can use matchers in both configuration and verification steps.

Creation

You have to use mock function to create your mock object. It works both with classes and functions.

Class example:

from mimid import mock

class A:

    def foo(self, param):
        pass

class_mock = mock(A) 

Function example:

from mimid import mock

def foo(param):
    pass

function_mock = mock(foo)

Configuration

Before you call your mock (function or method) you have to configure its behaviour. Use every with additional methods (returns, raises, ...) to define how it should works during your test.

from mimid import mock, every

def foo(param):
    pass

function_mock = mock(foo)
every(function_mock).returns(1)

You can also specify arguments which should trigger defined behaviour.

from mimid import mock, every

def foo(param):
    pass

function_mock = mock(foo)
every(function_mock).with_args(param=2).returns(1)
every(function_mock).with_args(param=3).raises(Exception())

Available configurations:

Configuration Description
returns return given value
returns_many return each value from provided list
raises raise given exception
execute call given callable

Verification

At the end of your test you can check if mock was called as expected with verify.

from mimid import mock, verify

def foo(param):
    pass

function_mock = mock(foo)

... # mock calls

verify(function_mock).called(times=2)

You can use the same with_args also during verification step:

from mimid import mock, every, verify

def foo(param):
    pass

function_mock = mock(foo)

... # mock calls

verify(function_mock).with_args(param=1).called(times=2)

Matchers

You can use matchers during configuration (with_args) and verification (with_args, called) steps. You can also combine matchers with | or & and negate it with ~.

Example:

from mimid import mock, every, verify, gt, lt, gte

def foo(param):
    pass

function_mock = mock(foo)
every(function_mock).with_args(gt(0)).returns(1)

result = function_mock(10)

assert result == 1
verify(function_mock).with_args(gt(5) | lt(15)).called(times=gte(1))

capture is a special matcher - it behaves like any() but additionally it stores given argument in provided slot.

Example:

from mimid import mock, every, slot, capture

def foo(param):
    pass

function_mock = mock(foo)
param_slot = slot()
every(function_mock).with_args(capture(param_slot)).execute(lambda: param_slot.value + 1)

result = function_mock(1)

assert result == 2
assert param_slot.value == 1

Available matchers:

Matcher Description
any match any value
eq match equal value
lt match lower value
lte match lower or equal value
gt match greater value
gte match greater or equal value
capture capture provided argument

Authors

Created by Konrad Hałas.

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

mimid-0.0.6.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

mimid-0.0.6-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file mimid-0.0.6.tar.gz.

File metadata

  • Download URL: mimid-0.0.6.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.1

File hashes

Hashes for mimid-0.0.6.tar.gz
Algorithm Hash digest
SHA256 49a8daf5de8ddf7e373d10ea9033f20d1492c5a4c2bf89b045223cf4bee0716c
MD5 7d45930af27f9c9d14da40780fc45868
BLAKE2b-256 69f48e99e612a118b0718c9469ca4f91a23317ce97174c966bcbec3acc21c940

See more details on using hashes here.

File details

Details for the file mimid-0.0.6-py3-none-any.whl.

File metadata

  • Download URL: mimid-0.0.6-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.1

File hashes

Hashes for mimid-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 5840fe0deeed22df68436c4cf2b625bbe9c54e62c14f8c9c30f6ce48492e6b5b
MD5 ceb2105ce24927368512ff08dccf2bd6
BLAKE2b-256 6635193f6d14350576f5956441538ca1dbc6fafc95ebf398fef08107f934ccd7

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