decoy

🦆 Opinionated mocking library for Python

https://github.com/mcous/decoy

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • â—‹
    CITATION.cff file
  • ✓
    codemeta.json file
    Found codemeta.json file
  • ✓
    .zenodo.json file
    Found .zenodo.json file
  • â—‹
    DOI references
  • â—‹
    Academic publication links
  • â—‹
    Committers with academic emails
  • â—‹
    Institutional organization owner
  • â—‹
    JOSS paper metadata
  • â—‹
    Scientific vocabulary similarity
    Low similarity (18.7%) to scientific vocabulary

Keywords

magicmock mock mockito spy stub tdd test testdouble

Keywords from Contributors

interactive serializer packaging network-simulation shellcodes hacking autograding observability genomics embedded
Last synced: 6 months ago · JSON representation

Repository

🦆 Opinionated mocking library for Python

Basic Info
Statistics
  • Stars: 32
  • Watchers: 2
  • Forks: 4
  • Open Issues: 8
  • Releases: 35
Topics
magicmock mock mockito spy stub tdd test testdouble
Created over 5 years ago · Last pushed 6 months ago
Metadata Files
Readme Contributing License Code of conduct

README.md

Decoy logo

Decoy

Opinionated mocking library for Python

Usage guide and documentation

Decoy is a mocking library designed for effective and productive test-driven development in Python. If you want to use tests to guide the structure of your code, Decoy might be for you!

Decoy mocks are async/await and type-checking friendly. Decoy is heavily inspired by (and/or stolen from) the excellent testdouble.js and Mockito projects. The Decoy API is powerful, easy to read, and strives to help you make good decisions about your code.

Install

```bash

pip

pip install decoy

poetry

poetry add --dev decoy

pipenv

pipenv install --dev decoy ```

Setup

Pytest setup

Decoy ships with its own pytest plugin, so once Decoy is installed, you're ready to start using it via its pytest fixture, called decoy.

```python

testmything.py

from decoy import Decoy

def testmything_works(decoy: Decoy) -> None: ... ```

Mypy setup

By default, Decoy is compatible with Python typing and type-checkers like mypy. However, stubbing functions that return None can trigger a type checking error during correct usage of the Decoy API. To suppress these errors, add Decoy's plugin to your mypy configuration.

```ini

mypy.ini

plugins = decoy.mypy ```

Other testing libraries

Decoy works well with pytest, but if you use another testing library or framework, you can still use Decoy! You just need to do two things:

  1. Create a new instance of Decoy() before each test
  2. Call decoy.reset() after each test

For example, using the built-in unittest framework, you would use the setUp fixture method to do self.decoy = Decoy() and the tearDown method to call self.decoy.reset(). For a working example, see tests/test_unittest.py.

Basic Usage

This basic example assumes you are using pytest. For more detailed documentation, see Decoy's usage guide and API reference.

Decoy will add a decoy fixture to pytest that provides its mock creation API.

```python from decoy import Decoy

def test_something(decoy: Decoy) -> None: ... ```

!!! note

Importing the `Decoy` interface for type annotations is recommended, but optional. If your project does not use type annotations, you can simply write:

```python
def test_something(decoy):
    ...
```

Create a mock

Use decoy.mock to create a mock based on some specification. From there, inject the mock into your test subject.

python def test_add_todo(decoy: Decoy) -> None: todo_store = decoy.mock(cls=TodoStore) subject = TodoAPI(store=todo_store) ...

See creating mocks for more details.

Stub a behavior

Use decoy.when to configure your mock's behaviors. For example, you can set the mock to return a certain value when called in a certain way using then_return:

```python def testaddtodo(decoy: Decoy) -> None: """Adding a todo should create a TodoItem in the TodoStore.""" todostore = decoy.mock(cls=TodoStore) subject = TodoAPI(store=todostore)

decoy.when(
    todo_store.add(name="Write a test for adding a todo")
).then_return(
    TodoItem(id="abc123", name="Write a test for adding a todo")
)

result = subject.add("Write a test for adding a todo")
assert result == TodoItem(id="abc123", name="Write a test for adding a todo")

```

See stubbing with when for more details.

Verify a call

Use decoy.verify to assert that a mock was called in a certain way. This is best used with dependencies that are being used for their side-effects and don't return a useful value.

```python def testremovetodo(decoy: Decoy) -> None: """Removing a todo should remove the item from the TodoStore.""" todostore = decoy.mock(cls=TodoStore) subject = TodoAPI(store=todostore)

subject.remove("abc123")

decoy.verify(todo_store.remove(id="abc123"), times=1)

```

See spying with verify for more details.

Owner

  • Name: Michael Cousins
  • Login: mcous
  • Kind: user
  • Location: Brooklyn, NY
  • Company: @abridgeai

/[a-z]+ware/ engineer at @abridgeai. Formerly @viamrobotics, @opentrons. Typically over-caffeinated.

GitHub Events

Total
  • Create event: 16
  • Release event: 1
  • Issues event: 4
  • Watch event: 4
  • Delete event: 12
  • Issue comment event: 30
  • Push event: 31
  • Pull request review event: 18
  • Pull request review comment event: 17
  • Pull request event: 25
  • Fork event: 2
Last Year
  • Create event: 16
  • Release event: 1
  • Issues event: 4
  • Watch event: 4
  • Delete event: 12
  • Issue comment event: 30
  • Push event: 31
  • Pull request review event: 18
  • Pull request review comment event: 17
  • Pull request event: 25
  • Fork event: 2

Committers

Last synced: 9 months ago

All Time
  • Total Commits: 222
  • Total Committers: 3
  • Avg Commits per committer: 74.0
  • Development Distribution Score (DDS): 0.441
Past Year
  • Commits: 3
  • Committers: 2
  • Avg Commits per committer: 1.5
  • Development Distribution Score (DDS): 0.333
Top Committers
Name Email Commits
Mike Cousins m****e@c****o 124
dependabot[bot] 4****] 97
Max Marrone m****x@m****c 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 14
  • Total pull requests: 194
  • Average time to close issues: about 1 month
  • Average time to close pull requests: 22 days
  • Total issue authors: 5
  • Total pull request authors: 5
  • Average comments per issue: 2.0
  • Average comments per pull request: 1.37
  • Merged pull requests: 110
  • Bot issues: 0
  • Bot pull requests: 147
Past Year
  • Issues: 1
  • Pull requests: 27
  • Average time to close issues: N/A
  • Average time to close pull requests: 10 days
  • Issue authors: 1
  • Pull request authors: 4
  • Average comments per issue: 2.0
  • Average comments per pull request: 1.0
  • Merged pull requests: 15
  • Bot issues: 0
  • Bot pull requests: 9
Top Authors
Issue Authors
  • mcous (7)
  • SyntaxColoring (2)
  • samuelint (2)
  • andreaevooq (2)
  • vishaltanwar96 (1)
Pull Request Authors
  • dependabot[bot] (147)
  • mcous (41)
  • samuelint (4)
  • Alejandro-FA (1)
  • SyntaxColoring (1)
Top Labels
Issue Labels
bug (3) enhancement (3) documentation (1) help wanted (1) question (1) wontfix (1)
Pull Request Labels
dependencies (147) python (138) github_actions (9) autorelease: pending (2) autorelease: tagged (1)

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 7,637 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 4
  • Total versions: 37
  • Total maintainers: 1
pypi.org: decoy

Opinionated mocking library for Python

  • Versions: 37
  • Dependent Packages: 0
  • Dependent Repositories: 4
  • Downloads: 7,637 Last month
Rankings
Downloads: 3.0%
Dependent repos count: 7.6%
Dependent packages count: 9.9%
Average: 11.6%
Stargazers count: 14.9%
Forks count: 22.7%
Maintainers (1)
Last synced: 6 months ago

Dependencies

poetry.lock pypi
  • astunparse 1.6.3 develop
  • atomicwrites 1.4.0 develop
  • attrs 21.2.0 develop
  • black 22.6.0 develop
  • cached-property 1.5.2 develop
  • chevron 0.14.0 develop
  • click 8.0.1 develop
  • colorama 0.4.4 develop
  • coverage 6.2 develop
  • dataclasses 0.8 develop
  • decorator 5.0.9 develop
  • execnet 1.9.0 develop
  • flake8 4.0.1 develop
  • flake8-annotations 2.7.0 develop
  • flake8-docstrings 1.6.0 develop
  • ghp-import 2.0.1 develop
  • importlib-metadata 4.2.0 develop
  • iniconfig 1.1.1 develop
  • jinja2 3.0.1 develop
  • markdown 3.3.4 develop
  • markupsafe 2.0.1 develop
  • mccabe 0.6.1 develop
  • mergedeep 1.3.4 develop
  • mkdocs 1.2.4 develop
  • mkdocs-autorefs 0.2.1 develop
  • mkdocs-material 8.2.7 develop
  • mkdocs-material-extensions 1.0.1 develop
  • mkdocstrings 0.16.2 develop
  • mypy 0.941 develop
  • mypy-extensions 0.4.3 develop
  • packaging 21.0 develop
  • pathspec 0.9.0 develop
  • platformdirs 2.4.0 develop
  • pluggy 0.13.1 develop
  • py 1.10.0 develop
  • pycodestyle 2.8.0 develop
  • pydocstyle 6.1.1 develop
  • pyflakes 2.4.0 develop
  • pygments 2.10.0 develop
  • pymdown-extensions 9.0 develop
  • pyparsing 2.4.7 develop
  • pytest 7.0.1 develop
  • pytest-asyncio 0.16.0 develop
  • pytest-forked 1.3.0 develop
  • pytest-mypy-plugins 1.9.3 develop
  • pytest-xdist 2.5.0 develop
  • python-dateutil 2.8.2 develop
  • pytkdocs 0.11.0 develop
  • pyyaml 5.4.1 develop
  • pyyaml-env-tag 0.1 develop
  • regex 2021.7.6 develop
  • six 1.16.0 develop
  • snowballstemmer 2.1.0 develop
  • tomli 1.1.0 develop
  • typed-ast 1.4.3 develop
  • typing-extensions 3.10.0.0 develop
  • watchdog 2.1.3 develop
  • zipp 3.5.0 develop
pyproject.toml pypi
  • black ^22.6 develop
  • coverage ^6.2 develop
  • flake8 ^4.0.1 develop
  • flake8-annotations ^2.7.0 develop
  • flake8-docstrings ^1.5.0 develop
  • mkdocs ^1.2.4 develop
  • mkdocs-material ^8.2.7 develop
  • mkdocstrings ^0.16.2 develop
  • mypy ^0.941 develop
  • pytest ^7.0.1 develop
  • pytest-asyncio ^0.16.0 develop
  • pytest-mypy-plugins ^1.9.3 develop
  • pytest-xdist ^2.5.0 develop
  • python ^3.6
.github/workflows/ci.yml actions
  • actions/cache v3 composite
  • actions/checkout v3 composite
  • actions/setup-python v4 composite
  • codecov/codecov-action v3 composite
.github/actions/setup/action.yml actions
  • actions/cache v3 composite
  • actions/setup-python v4 composite