This library allows you to create objects that impersonate other objects:
# pretend to be a pathlib.Path
path = pretend()
program = Program(path)
program.save('content')
assert_true(path.write_text.was_called_with('content'))
In tests.
Objects play with other objects. This makes it hard to test objects in isolation, because when you create them, you need to create their friends as well. This library allows you to provide friends for your object to play with.
So... like mocks?
Yes. Others call such objects mocks, stubs, dummies, spies, test doubles, or fakes. However, I find these terms unhelpful and confusing, which is why I try to avoid them.
Take a look at the tests. The tests explain how substitutes behave and can be used as examples.
https://github.com/cessor/kazookid/blob/master/test/test_substitute.py
You always start with pretend
. Pretend creates a Substitute
object. You can also create them directly. However if you know the kazookid, the pretend function might be more memorable.
from kazookid import pretend
# ...
path = pretend()
Then you configure what the substitute should do:
path.read_text.returns('content')
Then you pass the object to the actual component that you would like to test:
# Arrange
path = pretend()
path.read_text.returns('1 2 3 4')
# System under Test
# SquareNumbers implements an iterator.
square_numbers = SquareNumbers(read_from=path)
# Act
result = list(square_numbers)
# Assert
assert_equal(result, [1, 4, 9, 16])
- How to create a Substitute
- How to call a method on a substitute
- How to provide data from a property
- How to provide data from a method
- How to provide data for iteration
- How to raise exceptions
- How to intercept the arguments of a call
- How to verify that a method was called
- How to verify that a method was called several times
- How to verify that a method was called with specific arguments
- Properties containing functions are methods
- When a call had many arguments, they are returned as a tuple
- When a method was called several times, all arguments are stored
There is also a substitute for context managers:
Named after the kazookid: https://www.youtube.com/watch?v=D06m5ndmVsM
This is a simplified implementation of my original framework, https://github.com/cessor/substitute, which was getting too complex.