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!
A test utility library to help write explict side effects for mocked objects
A test utility library to help write explict side effects for mocked objects.
Mocks side effects are manipulated by when
and then
functions.
mock.when(...).then(...)
To enable this extend the mock class in you tests.
import known_side_effects
from unittest.mock import Mock
...
known_side_effects.extend(Mock)
All parameters in the when
function are used to define the expected parameters for the side effect.
mock.when('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 mock.when('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.
mock.when('first_specified_argument').then(...)
mock.when('second_specified_argument').then(...)
mock.when('third_specified_argument').then(...)
Calling the when function with exactly the same arguments will allow you to append to the responses.
mock.when('arg').then('response_one')
mock.when('arg').then('response_two')
is the same as
mock.when('arg').then('response_one').then('response_two')
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
...
response_one = Mock()
mock = Mock()
mock.when(...).then(response_one)
assert mock(...) == response_one
To raise an exception rather that return a value call then_raise
rather than then
. An exception will be raised instead of returned.
from unittest.mock import Mock
...
exception = Exception()
mock = Mock()
mock.when(...).then_raise(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
...
exception = Exception()
response_one = Mock()
mock = Mock()
mock.when(...).then(response_one).then_raise(exception)
assert mock(...) == response_one
mock(...) # Raises the exception
mock(...) # Raises the exception
You can specify default return values on a mock by calling otherwise. If the mock is called without matching any arguments then the otherwise value will returned.
mock.when('arg').then(...).otherwise('otherwise')
assert mock('not arg') == 'otherwise'
You can also raise an exception by default
mock.when(...).then(...).otherwise_raise(Exception())
You can specify the mock to always return the same response regardless of what arguments it is called with.
mock.when().always('response')
assert mock(...) == 'response'
You can also raise an exception
mock.when().always_raise(Exception())
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 reset
...
mock = Mock()
mock.when(...).then(...)
reset(mock)
mock(...) # raises an UnmatchedArguments exception
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 AnyArg
...
response_one = Mock()
response_two = Mock()
argument_one = Mock()
argument_two = Mock()
mock.when(argument_one).then(response_one)
mock.when(AnyArg()).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 AnyArg
...
response_one = Mock()
response_two = Mock()
argument_one = Mock()
argument_two = Mock()
mock.when(AnyArg()).then(response_two) # These two lines have swapped
mock.when(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 can be passed to known side effects as parameters. They are implementations of hamcrest matchers. Matchers will only match a single parameter.
FAQs
A test utility library to help write explict side effects for mocked objects
We found that known-side-effects 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.