decoy 2.1.1

Creator: bradpython12

Last updated:

Add to Cart

Description:

decoy 2.1.1

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
# 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.
# test_my_thing.py
from decoy import Decoy

def test_my_thing_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.
# 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:

Create a new instance of Decoy() before each test
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.
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.
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:
def test_add_todo(decoy: Decoy) -> None:
"""Adding a todo should create a TodoItem in the TodoStore."""
todo_store = decoy.mock(cls=TodoStore)
subject = TodoAPI(store=todo_store)

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.
def test_remove_todo(decoy: Decoy) -> None:
"""Removing a todo should remove the item from the TodoStore."""
todo_store = decoy.mock(cls=TodoStore)
subject = TodoAPI(store=todo_store)

subject.remove("abc123")

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

See spying with verify for more details.

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.