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 - not 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())

If you want to define property behaviour you have to use prop function:

from mimid import mock, every, prop

class A:
    
    @property
    def x(self) -> int:
        pass
        
class_mock = mock(A) 
every(prop(class_mock).x).returns(1)

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, 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.10.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

mimid-0.0.10-py3-none-any.whl (9.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mimid-0.0.10.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.1

File hashes

Hashes for mimid-0.0.10.tar.gz
Algorithm Hash digest
SHA256 165542c11de4c803315ccc5518ab934351d82d84fc715040468b018ef65a7c1c
MD5 ea3421515f6579c0a60aed43e0ae7502
BLAKE2b-256 de3526182776ea7b0c1cb970a4c98f47a53414d215b7439e72e157cd13fae938

See more details on using hashes here.

File details

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

File metadata

  • Download URL: mimid-0.0.10-py3-none-any.whl
  • Upload date:
  • Size: 9.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.1

File hashes

Hashes for mimid-0.0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 ab28ce47a9ac4012c9186435a9fdac63df04991ace9fc76856e5bfedc16224f1
MD5 8617a574db024f58d045be24e753d465
BLAKE2b-256 177e7973005e2d4e43db450963dd2b47cc7393a7ad993e117dba9f927d5e8f0b

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