Почему патчи не работают при запуске тестов Django через ./manage.py?

Как исправить проблему, при которой в методе patch в тестовом классе не происходит переопределение функции при запуске через командную строку python3 manage.py test? В PyCharm переопределенная функция вызывается успешно при нажатии на кнопку, но при запуске из командной строки используется не пропатченная функция. Как можно исправить это поведение, чтобы переопределенная функция работала при запуске из обеих сред? Если указать конкретный класс для запуска, то проблемы не возникает, но проблемы появляются, когда указывается директория.
  • 15 ноября 2023 г. 9:55
Ответы на вопрос 2
Проблема, скорее всего, связана с тем, что при запуске тестов через команду `./manage.py test`, Django использует собственный механизм поиска и загрузки тестовых классов, который может приводить к игнорированию переопределенных методов, патчей и моков.

Для исправления этой проблемы можно применить следующие подходы:

1. Используйте декоратор `override_settings` вместо `patch`, чтобы переопределить настройки Django для тестового класса. Например:
```python
from django.test import TestCase, override_settings

@override_settings(MY_SETTING='new_value')
class MyTestCase(TestCase):
    ...
```
Декоратор `override_settings` переопределит значение `MY_SETTING` только для этого тестового класса.

2. Если вам нужно переопределить метод, который вызывается до запуска тестов, вы можете использовать декоратор `@classmethod` и изменить его поведение. Например:
```python
from django.test import TestCase

class MyTestCase(TestCase):
    @classmethod
    def setUpTestData(cls):
        super().setUpTestData()
        # Ваш код для переопределения метода setUpTestData()
```

3. Если источник проблемы связан с загрузкой тестов из директории, попробуйте явно указать путь к вашему тестовому классу при запуске команды `./manage.py test`. Например:
```
./manage.py test my_app.tests.MyTestCase
```
где `my_app.tests.MyTestCase` - путь к вашему тестовому классу.

Надеюсь, эти подходы помогут вам исправить проблему с применением патчей и переопределением методов при запуске тестов в Django.
Скорее всего, проблема заключается в том, что вы пытаетесь применить патч к модулю или объекту, который импортируется до того, как будет применен патч. Вместо этого, вам нужно применять патч к модулю или объекту, который импортируется непосредственно в ваш модуль, где проводятся тесты.

Например, если у вас есть функция foo в модуле mypackage.mymodule, которая использует функцию urlopen из модуля urllib:

from urllib.request import urlopen

def foo():
  ...

И вы хотите написать тесты для этой функции, где хотите применить патч к вызову urlopen. Неправильный вариант:

@patch("urllib.request.urlopen")
def test(urlopen):
  ...

Правильный вариант:

@patch("mypackage.mymodule.urlopen")
def test(urlopen):
  ...

UPD: Если возможно, предоставьте код теста и код тестируемой функции для более точной помощи.
Похожие вопросы