Python Mocking with unitest.mock 2
Internal
Mocking a Method
The general approach is to replace at runtime the real method instance associated with the class instance to be tested with a Mock
instance, configured to simulate various behaviors of the real method.
Assuming that our dependency to test with is SomeClass
, and this class has a some_method(nuance: str)
whose behavior we want to mock during testing, the initial implementation of the class and method could be:
class SomeClass:
def __init__(self, color: str):
self._color = color
def some_method(self, nuance: str) -> str:
return f'{nuance} {self._color}'.upper()
The normal behavior of the method some_method(nuance: str)
is reflected by:
c = SomeClass('blue')
assert c.some_method('dark') == 'DARK BLUE'
c._color = 'red'
assert c.some_method('light') == 'LIGHT RED'
We can mock the behavior of the some_method(nuance: str)
method in the following ways:
- We can return a constant value, regardless of the arguments the method is invoked with.
- We can raise an exception, regardless of the arguments the method is invoked with.
- We can replace the behavior of the method with custom logic, that takes into account the arguments the method is called with.
Simulating a Particular Return Value Irrespective of the Arguments it was Called With
Configure Mock()
using the return_value
argument of its constructor so no matter how the mocked method is invoked, it will always return a constant value:
c = SomeClass('blue')
c.some_method = Mock(return_value='something completely arbitrary')
assert c.some_method('argument does not matter') == 'something completely arbitrary'
Irrespective of how the method is invoked in testing, the calling code will always get the value configured with return_value
on the mock.