Skip to main content

A test utility library to help write explict side effects for mocked objects

Project description

Known Side Effects

Codacy Badge Coverage Badge Python version badge Licence badge

A test utility library to help write explict side effects for mocked objects.

Mocks side effects are manipulated by when and then functions.

from known_side_effects import when
...
when(...).then(...)

You manipulate a specific mocks side effect by passing them to the first parameter in the when function.

from known_side_effects import when
...
when(mock, ...).then(...)

When

All parameters in the when function after the mock, are used to define the expected parameters for the side effect.

from known_side_effects import when
...
when(mock, 'argument_one', arg='argument_two').then(...)

If the mock is called with parameters that don't match any of the specified parameter sets then an UnmatchedArguments exception is raised. The arguments have to match exactly.

E.g. Given when(mock, 'argument_one', arg='argument_two').then(...) when the mock is called with the parameters in the table below an UnmatchedArguments is either raised or not raised.

Parameters Raises
mock('argument_one', arg='argument_two') False
mock(arg='argument_two') True
mock('argument_one') True

Multiple sets of parameters to match can be specified.

from known_side_effects import when
...
when(mock, 'first_specified_argument').then(...)
when(mock, 'second_specified_argument').then(...)
when(mock, 'third_specified_argument').then(...)

Then

The then function specifies what the known side effect should do when parameters are matched. By default it will just return what has been passed into the then function.

from unittest.mock import Mock
from known_side_effects import when, Any
...
response_one = Mock()
mock = Mock()

when(mock, ...).then(response_one)

assert mock(...) == response_one

However if the parameter is an instance of an exception then, when the known side effect is matched the exception will be raised instead of returned.s

from unittest.mock import Mock
from known_side_effects import when, Any
...
exception = Exception()
mock = Mock()

when(mock, ...).then(exception)

mock(...)  # Raises the exception

You can also chain the then functions to return multiple different reponses. Each response will be returned once until the last response. Once the last response is reached then that reponse will be the only thing returned.

from unittest.mock import Mock
from known_side_effects import when, Any
...
exception = Exception()
response_one = Mock()
mock = Mock()

when(mock, ...).then(response_one).then(exception)

assert mock(...) == response_one
mock(...)  # Raises the exception
mock(...)  # Raises the exception

Reset

You can reset the the known side effects on a mock by passing it the reset function.

from unittest.mock import Mock
from known_side_effects import when, reset
...

mock = Mock()

when(mock, ...).then(...)

reset(mock)

mock(...)  # raises an UnmatchedArguments exception

Gotcha

When calling the mock after specifying multiple known side effects, the first matched set of parameters will be executed. The order of matching is the order that the known side effects are defined in. If multiple arguments are specified where one matches a super set of the other (see Matchers) then the first matched will be executed. e.g.

from unittest.mock import Mock
from known_side_effects import when, Any
...
response_one = Mock()
response_two = Mock()
argument_one = Mock()
argument_two = Mock()

when(mock, argument_one).then(response_one)
when(mock, Any()).then(response_two)
...
assert mock(argument_one) == response_one
assert mock(argument_two) == response_two

If the order of the known side effects were reversed, the mock would only ever return response_two. This is due to the fact that the Any matched will match all parameters, therefore never attempting to match argument_one as it has already found a match. e.g.

from unittest.mock import Mock
from known_side_effects import when, Any
...
response_one = Mock()
response_two = Mock()
argument_one = Mock()
argument_two = Mock()

when(mock, Any()).then(response_two)        # These two lines have swapped
when(mock, argument_one).then(response_one) # These two lines have swapped

...
# This will raise an AssertionError as calling the mock with argument_one now
# returns response_two and not response_one
assert mock(argument_one) == response_one   
assert mock(argument_two) == response_two

Matchers

Matchers can be passed to known side effects as parameters. They are implementations of hamcrest matchers. Matchers will only match a single parameter.

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

known_side_effects-0.0.2.tar.gz (5.3 kB view hashes)

Uploaded Source

Built Distribution

known_side_effects-0.0.2-py2.py3-none-any.whl (10.6 kB view hashes)

Uploaded Python 2 Python 3

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