Product
Introducing License Enforcement in Socket
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
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.
# pip
pip install decoy
# poetry
poetry add --dev decoy
# pipenv
pipenv install --dev decoy
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:
...
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
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:
Decoy()
before each testdecoy.reset()
after each testFor 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
.
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):
...
```
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.
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.
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.
FAQs
Opinionated mocking library for Python
We found that decoy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Product
We're launching a new set of license analysis and compliance features for analyzing, managing, and complying with licenses across a range of supported languages and ecosystems.
Product
We're excited to introduce Socket Optimize, a powerful CLI command to secure open source dependencies with tested, optimized package overrides.