mock
- mock - пакет для создания заглушек
- Напр. чтобы не кидать реальный http-запрос к какой-нибудь апишке, лучше замокать/застабить/написать заглушку - это дает предсказуемость и скорость
Как мокать assert_called_with
, если один из параметров - дичь или не важен?
Использовать mock.ANY
assert_called_with(mock.ANY, ...)
Моканье методов
Как мокать методы у мок-объектов?
dadata_service_mock = MagicMock()
get_houses_by_coordinates_mock = dadata_service_mock.get_houses_by_coordinates
get_houses_by_coordinates_mock.return_value = dadata_addresses
assert dadata_service_mock.get_houses_by_coordinates(*args, **kwargs) == dadata_addresses
Как мокать объекты?
Использовать mock.patch.object
:
@mock.patch.object(
GetAccessTokenForFCM,
'__call__',
)
def test_setup_fcm(
GetAccessTokenForFCM_mock, # type: mock.MagicMock
):
GetAccessTokenForFCM_mock.return_value = 'token'
assert GetAccessTokenForFCM()() == 'token'
Здесь классу GetAccessTokenForFCM
мокаем метод __call__
. Теперь при вызове метода __call__
объект будет всегда
возвращать токен.
Очередность моков
- При использовании моков-декораторов, очередность моков происходит снизу вверх:
@mock.patch('methods.push.send_client_push')
@mock.patch('methods.empatika_promos.deposit_user_points')
def test_deposit_points_or_cashback_for_points_positive(
deposit_user_points_mock, # type: mock.MagicMock
send_client_push_mock, # type: mock.MagicMock
mock_gae
):
...
- Первым моком будет
deposit_user_points
- Вторым моком будет
send_client_push
- Дальше идут фикстуры
- А еще можно вместо декоратора использовать контекст менеджеры
Разные моки при очередном вызове
- Напр. нужно сгенерировать разные uuid, или разные http-ответы
@patch.object(uuid, 'uuid4', side_effect=TEST_UUIDS)
- Вместо передачи заглушки в
return_value
, передаем список заглушек вside_effect
- Источник