Проблема здесь в том, что вы, по сути, делаете следующее:
from deals.services.services import is_user_valid
import deals.services.services
deals.services.services.is_user_valid = Mock(return_value=True)
# call local is_user_valid
Импортируя сам символ «терминала», вы исключаете любую возможность издевательства, теперь это локальная ссылка, и поэтому обновление «удаленной» ссылки не повлияет на локальную версию. Это означает, что вы должны держать дескриптор самого модуля , чтобы соответствующий символ разрешался при каждом доступе:
from deals.services import services
def test_api(mocker):
mocker.patch('deals.services.services.is_user_valid', return_value=True)
print(services.is_user_valid("sdfds", "sdfsdf"))
должно работать лучше.
Это также проблема с любым модулем, использующим такой импорт, они требуют исправления точки использования, а не точки определения , потому что к моменту запуска макета вероятность того, что пользовательский модуль уже имеет свою копию .
См. документацию для получения более подробной информации.