Skip to content

API Reference#

decoy.Decoy #

Decoy mock factory and state container.

You should create a new Decoy instance before each test and call reset after each test. If you use the decoy pytest fixture, this is done automatically. See the setup guide for more details.

Example

decoy = Decoy()

# test your subject
...

decoy.reset()

decoy.Decoy.mock(*, cls=None, func=None, name=None, is_async=False) #

Create a mock. See the mock creation guide for more details.

Parameters:

Name Type Description Default
cls Optional[Any]

A class definition that the mock should imitate.

None
func Optional[Any]

A function definition the mock should imitate.

None
name Optional[str]

A name to use for the mock. If you do not use cls or func, you should add a name.

None
is_async bool

Force the returned spy to be asynchronous. This argument only applies if you don't use cls nor func.

False

Returns:

Type Description
Any

A spy typecast as the object it's imitating, if any.

Example

def test_get_something(decoy: Decoy):
    db = decoy.mock(cls=Database)
    # ...

decoy.Decoy.prop(_rehearsal_result) #

Create property setter and deleter rehearsals.

See property mocking guide for more details.

Parameters:

Name Type Description Default
_rehearsal_result ReturnT

The property to mock, for typechecking.

required

Returns:

Type Description
Prop[ReturnT]

A prop rehearser on which you can call set or

Prop[ReturnT]

delete to create property rehearsals.

decoy.Decoy.reset() #

Reset all mock state.

This method should be called after every test to ensure spies and stubs don't leak between tests. The decoy fixture provided by the pytest plugin will call reset automatically.

The reset method may also trigger warnings if Decoy detects any questionable mock usage. See decoy.warnings for more details.

decoy.Decoy.verify(*_rehearsal_results, times=None, ignore_extra_args=False) #

Verify a mock was called using one or more rehearsals.

See verification usage guide for more details.

Parameters:

Name Type Description Default
_rehearsal_results Any

The return value of rehearsals, unused except to determine how many rehearsals to verify.

()
times Optional[int]

How many times the call should appear. If times is specified, the call count must match exactly, otherwise the call must appear at least once. The times argument must be used with exactly one rehearsal.

None
ignore_extra_args bool

Allow the rehearsal to specify fewer arguments than the actual call. Decoy will compare and match any given arguments, ignoring unspecified arguments.

False

Raises:

Type Description
VerifyError

The verification was not satisfied.

Example

def test_create_something(decoy: Decoy):
    gen_id = decoy.mock(func=generate_unique_id)

    # ...

    decoy.verify(gen_id("model-prefix_"))

Note

A "rehearsal" is an actual call to the test fake. The fact that the call is written inside verify is purely for typechecking and API sugar. Decoy will pop the last call(s) to any fake off its call stack, which will end up being the call inside verify.

decoy.Decoy.when(_rehearsal_result, *, ignore_extra_args=False) #

Create a Stub configuration using a rehearsal call.

See stubbing usage guide for more details.

Parameters:

Name Type Description Default
_rehearsal_result ReturnT

The return value of a rehearsal, used for typechecking.

required
ignore_extra_args bool

Allow the rehearsal to specify fewer arguments than the actual call. Decoy will compare and match any given arguments, ignoring unspecified arguments.

False

Returns:

Type Description
Stub[ReturnT]

A stub to configure using then_return,

Stub[ReturnT]
Stub[ReturnT]

Example

db = decoy.mock(cls=Database)
decoy.when(db.exists("some-id")).then_return(True)

Note

The "rehearsal" is an actual call to the test fake. Because the call is written inside when, Decoy is able to infer that the call is a rehearsal for stub configuration purposes rather than a call from the code-under-test.

decoy.Stub #

Bases: Generic[ReturnT]

A rehearsed Stub that can be used to configure mock behaviors.

See stubbing usage guide for more details.

decoy.Stub.then_do(action) #

Configure the stub to trigger an action.

Parameters:

Name Type Description Default
action Callable[..., Union[ReturnT, Coroutine[Any, Any, ReturnT]]]

The function to call. Called with whatever arguments are actually passed to the stub. May be an async def function if the mock is also asynchronous.

required

Raises:

Type Description
MockNotAsyncError

action was an async def function, but the mock is synchronous.

decoy.Stub.then_enter_with(value) #

Configure the stub to return a value wrapped in a context manager.

The wrapping context manager is compatible with both the synchronous and asynchronous context manager interfaces.

See the context manager usage guide for more details.

Parameters:

Name Type Description Default
value ContextValueT

A return value to wrap in a ContextManager.

required

decoy.Stub.then_raise(error) #

Configure the stub to raise an error.

Parameters:

Name Type Description Default
error Exception

The error to raise.

required

Note

Setting a stub to raise will prevent you from writing new rehearsals, because they will raise. If you need to make more calls to when, you'll need to wrap your rehearsal in a try.

decoy.Stub.then_return(*values) #

Configure the stub to return value(s).

Parameters:

Name Type Description Default
*values ReturnT

Zero or more return values. Multiple values will result in different return values for subsequent calls, with the last value latching in once all other values have returned.

()

decoy.Prop #

Bases: Generic[ReturnT]

Rehearsal creator for mocking property setters and deleters.

See property mocking guide for more details.

decoy.Prop.delete() #

Create a property deleter rehearsal.

By wrapping delete in a call to when or verify, you can stub or verify a call to a property deleter.

Example

some_obj = decoy.mock()
del some_obj.prop
decoy.verify(decoy.prop(some_obj.prop).delete())

decoy.Prop.set(value) #

Create a property setter rehearsal.

By wrapping set in a call to when or verify, you can stub or verify a call to a property setter.

Parameters:

Name Type Description Default
value ReturnT

The value

required

Example

some_obj = decoy.mock()
some_obj.prop = 42
decoy.verify(decoy.prop(some_obj.prop).set(42))

decoy.matchers #

Matcher helpers.

A "matcher" is a class with an __eq__ method defined. Use them anywhere in your test where you would use an actual value for equality (==) comparison.

Matchers help you loosen assertions where strict adherence to an exact value is not relevant to what you're trying to test. See the matchers guide for more details.

Example

from decoy import Decoy, matchers

# ...

def test_logger_called(decoy: Decoy):
    # ...
    decoy.verify(
        logger.log(msg=matchers.StringMatching("hello"))
    )

Note

Identity comparisons (is) will not work with matchers. Decoy only uses equality comparisons (==) for stubbing and verification.

decoy.matchers.Anything() #

Match anything except None.

Example

assert "foobar" == Anything()
assert None != Anything()

decoy.matchers.Captor() #

Match anything, capturing its value.

The last captured value will be set to captor.value. All captured values will be placed in the captor.values list, which can be helpful if a captor needs to be triggered multiple times.

Example

captor = Captor()
assert "foobar" == captor
print(captor.value)  # "foobar"
print(captor.values)  # ["foobar"]

decoy.matchers.DictMatching(values) #

Match any dictionary with the passed in keys / values.

Parameters:

Name Type Description Default
values Mapping[str, Any]

Keys and values to check.

required

Example

value = {"hello": "world", "goodbye": "so long"}
assert value == matchers.DictMatching({"hello": "world"})

decoy.matchers.ErrorMatching(error, match=None) #

Match any error matching an Exception type and optional message matcher.

Parameters:

Name Type Description Default
error Type[ErrorT]

Exception type to match against.

required
match Optional[str]

Pattern to check against; will be compiled into an re.Pattern.

None

Example

assert ValueError("oh no!") == ErrorMatching(ValueError)
assert ValueError("oh no!") == ErrorMatching(ValueError, match="no")

decoy.matchers.HasAttributes(attributes) #

Match anything with the passed in attributes.

Parameters:

Name Type Description Default
attributes Mapping[str, Any]

Attribute values to check.

required

Example

@dataclass
class HelloWorld:
    hello: str = "world"
    goodby: str = "so long"

assert HelloWorld() == matchers.HasAttributes({"hello": "world"})

decoy.matchers.IsA(match_type, attributes=None) #

Match anything that satisfies the passed in type.

Parameters:

Name Type Description Default
match_type type

Type to match.

required
attributes Optional[Mapping[str, Any]]

Optional set of attributes to match

None

Example

assert "foobar" == IsA(str)
assert datetime.now() == IsA(datetime)
assert 42 == IsA(int)

@dataclass
class HelloWorld:
    hello: str = "world"
    goodby: str = "so long"

assert HelloWorld() == IsA(HelloWorld, {"hello": "world"})

decoy.matchers.IsNot(value) #

Match anything that isn't the passed in value.

Parameters:

Name Type Description Default
value object

Value to check against.

required

Example

assert "foobar" == IsNot("bazquux")
assert 42 == IsNot("the question")
assert 1 != IsNot(1)

decoy.matchers.StringMatching(match) #

Match any string matching the passed in pattern.

Parameters:

Name Type Description Default
match str

Pattern to check against; will be compiled into an re.Pattern.

required

Example

assert "foobar" == StringMatching("bar")
assert "foobar" != StringMatching("^bar")

decoy.errors #

Errors raised by Decoy.

See the errors guide for more details.

decoy.errors.MissingRehearsalError #

Bases: ValueError

An error raised when a Decoy method is called without rehearsal(s).

This error is raised if you use when, verify, or prop incorrectly in your tests. When using async/await, this error can be triggered if you forget to include await with your rehearsal.

See the MissingRehearsalError guide for more details.

decoy.errors.MockNameRequiredError #

Bases: ValueError

An error raised if a name is not provided for a mock.

See the MockNameRequiredError guide for more details.

decoy.errors.MockNotAsyncError #

Bases: TypeError

An error raised when an asynchronous function is used with a synchronous mock.

This error is raised if you pass an async def function to a synchronous stub's then_do method. See the MockNotAsyncError guide for more details.

decoy.errors.VerifyError #

Bases: AssertionError

An error raised when actual calls do not match rehearsals given to verify.

See spying with verify for more details.

Attributes:

Name Type Description
rehearsals Sequence[VerifyRehearsal]

Rehearsals that were being verified.

calls Sequence[SpyEvent]

Actual calls to the mock(s).

times Optional[int]

The expected number of calls to the mock, if any.

decoy.warnings #

Warnings raised by Decoy.

See the warnings guide for more details.

decoy.warnings.DecoyWarning #

Bases: UserWarning

Base class for Decoy warnings.

decoy.warnings.IncorrectCallWarning #

Bases: DecoyWarning

A warning raised if a Decoy mock with a spec is called incorrectly.

If a call to a Decoy mock is incorrect according to inspect.signature, this warning will be raised. See the IncorrectCallWarning guide for more details.

decoy.warnings.MiscalledStubWarning #

Bases: DecoyWarning

A warning when a configured Stub is called with non-matching arguments.

This warning is raised if a mock is both:

  • Configured as a stub with when
  • Called with arguments that do not match any configured behaviors

See the MiscalledStubWarning guide for more details.

Attributes:

Name Type Description
rehearsals Sequence[SpyRehearsal]

The mocks's configured rehearsals.

calls Sequence[SpyEvent]

Actual calls to the mock.

decoy.warnings.MissingSpecAttributeWarning #

Bases: DecoyWarning

A warning raised if a Decoy mock with a spec is used with a missing attribute.

This will become an error in the next major version of Decoy. See the MissingSpecAttributeWarning guide for more details.

decoy.warnings.RedundantVerifyWarning #

Bases: DecoyWarning

A warning when a mock is redundantly checked with verify.

A verify assertion is redundant if:

  • A given call is used as a when rehearsal
  • That same call is later used in a verify check

See the RedundantVerifyWarning guide for more details.

decoy.pytest_plugin #

Pytest plugin to setup and teardown a Decoy instance.

The plugin will be registered with pytest when you install Decoy. It adds a fixture without modifying any other pytest behavior. Its usage is optional but highly recommended.

decoy.pytest_plugin.decoy() #

Get a decoy.Decoy container and reset it after the test.

This function is function-scoped pytest fixture that will be automatically inserted by the plugin.

Example

def test_my_thing(decoy: Decoy) -> None:
    my_fake_func = decoy.mock()
    # ...