If for some reason you do need a teardown step from within the test itself, then you want the plain old mock API which also works fine within pytest.
from unittest.mock
import patch
def test_main_2():
with patch('module_a.MyClass.value', return_value = 20):
value = AnotherClass().get_value()
assert value == 20
value = AnotherClass().get_value()
assert value == 10
The patch() decorator / context manager makes it easy to mock classes or objects in a module under test. The object you specify will be replaced with a mock (or other object) during the test and restored when the test ends:,The patch() decorators makes it easy to temporarily replace classes in a particular module with a Mock object. By default patch() will create a MagicMock for you. You can specify an alternative class of Mock using the new_callable argument to patch().,new_callable allows you to specify a different class, or callable object, that will be called to create the new object. By default AsyncMock is used for async functions and MagicMock for the rest.,If a mock instance with a name or a spec is assigned to an attribute it won’t be considered in the sealing chain. This allows one to prevent seal from fixing part of the mock object.
>>> from unittest.mock
import MagicMock
>>>
thing = ProductionClass() >>>
thing.method = MagicMock(return_value = 3) >>>
thing.method(3, 4, 5, key = 'value')
3
>>>
thing.method.assert_called_with(3, 4, 5, key = 'value')
>>> mock = Mock(side_effect = KeyError('foo')) >>>
mock()
Traceback(most recent call last):
...
KeyError: 'foo'
>>> values = {
'a': 1,
'b': 2,
'c': 3
} >>>
def side_effect(arg):
...
return values[arg]
...
>>>
mock.side_effect = side_effect >>>
mock('a'), mock('b'), mock('c')
(1, 2, 3) >>>
mock.side_effect = [5, 4, 3, 2, 1] >>>
mock(), mock(), mock()
(5, 4, 3)
>>> from unittest.mock
import patch
>>>
@patch('module.ClassName2')
...@patch('module.ClassName1')
...def test(MockClass1, MockClass2):
...module.ClassName1()
...module.ClassName2()
...assert MockClass1 is module.ClassName1
...assert MockClass2 is module.ClassName2
...assert MockClass1.called
...assert MockClass2.called
...
>>>
test()
>>> with patch.object(ProductionClass, 'method', return_value = None) as mock_method:
...thing = ProductionClass()
...thing.method(1, 2, 3)
...
>>>
mock_method.assert_called_once_with(1, 2, 3)
>>> foo = {
'key': 'value'
} >>>
original = foo.copy() >>>
with patch.dict(foo, {
'newkey': 'newvalue'
}, clear = True):
...assert foo == {
'newkey': 'newvalue'
}
...
>>>
assert foo == original
The context manager produces an ExceptionInfo object which can be used to inspect the details of the captured exception:,See the section Where to patch in the unittest.mock docs for a complete explanation, which is meant for unittest.mock.patch() but applies to monkeypatch.setattr as well.,Similar to caught exception objects in Python, explicitly clearing local references to returned ExceptionInfo objects can help the Python interpreter speed up its garbage collection.,It provides an empty directory where pytest can be executed in isolation, and contains facilities to write tests, configuration files, and match against expected output.
>>>
import pytest
>>>
pytest.__version__ '7.0.0'
>>>
import pytest
>>>
pytest.version_tuple(7, 0, 0)
>>>
import pytest
>>>
pytest.version_tuple(7, 0, '0rc1')
>>> 0.1 + 0.2 == 0.3 False
>>> abs((0.1 + 0.2) - 0.3) < 1e-6 True
>>> from pytest
import approx
>>>
0.1 + 0.2 == approx(0.3)
True
In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when a real object is impractical or impossible to incorporate into a unit test. If an actual object has any of the following characteristics, it may be useful to use a mock object in its place:,it does not yet exist or may change behavior,Mock objects are simulated objects that mimic the behavior of real objects in a controlled way.,has some undesired side-effects in the context of your unit-tests
1 2 3 4 5
>>>
import mock
>>>
mock_obj = mock.Mock(x = 3) >>>
mock_obj.y = 2 >>>
mock_obj.x, mock_obj.y(3, 2)
1 2 3
>>> mock_obj.foo.return_value = 'val' >>>
mock_obj.foo('bar')
'val'
>>> mock_obj.open_file.side_effect = [IOError('File not found')] >>>
mock_obj.open_file()
Traceback(most recent call last):
...
IOError: File not found
>>> mock_obj.file_exists.side_effect = [True, False] >>>
mock_obj.file_exists('filename')
True
>>>
mock_obj.file_exists('filename')
False