Как смоделировать оценку глобальной переменной для нескольких тестов? - PullRequest
0 голосов
/ 04 апреля 2019

Мне нужно смоделировать глобальную переменную внутри скрипта Python.

Эта переменная инициализируется с использованием довольно дорогого метода, который также выбрасывается при запуске вне целевой среды.

Я узнал, как смоделировать эту переменную один раз, однако последующие имитации, похоже, не изменяют исходную (примеры приведены).

Тестируемый скрипт: сервис / организация / список / SRC / handler.py

from util.table import get_table

table = get_table('TABLE')

def query_db(event):
    query_args = create_query_params(event)
    query_res = table.query(**query_args)
    return query_res

Функция мне нужно издеваться: Util / table.py

def get_table(table_name):
    return get_db().table(table_name)

Что я пробовал:

  1. Насмешка, где это используется
class TestListEntities(TestCase):
    def setUp(self):
        self.event = MagicMock(name='event mock')
        self.table = MagicMock(name='table mock')
        self.query = MagicMock(name='query mock')
        self.query_result = {'items': []}
        self.table.query.return_value = self.query_result

    def test_empty(self):
        with patch('service.entity.list.src.handler.get_table', return_value=self.table):
            from service.entity.list.src.handler import query_db
            response = query_db(self.event)

            self.assertTrue(self.table.query.called)

это вызывает реальный метод еще до запуска теста.

  1. Насмешка, где это реализовано
    def test_empty(self):
        with patch('util.table.get_table', return_value=self.table):
            from service.entity.list.src.handler import query_db
            response = query_db(self.event)
            self.assertTrue(self.table.query.called)

Работает как положено, но исправления в других тестовых примерах не изменяют это исправление, и тесты не выполняются.

TL; DR Мне нужно исправить глобальную переменную инициализации для нескольких тестовых случаев, но удалось сделать это только один раз.

Ответы [ 2 ]

0 голосов
/ 17 апреля 2019

Моя рекомендация - заменить доступ к глобальным переменным методами получения.

С одной стороны, это может помочь решить вашу текущую проблему: вы можете заставить метод getter инициализировать переменную при первом вызове. Поэтому, если вы смоделируете это перед первым вызовом, истинная функция инициализации не будет вызвана.

Функции получателя также предоставляют больше свободы, чем прямой доступ к переменным в других случаях, а именно, когда вы хотите смоделировать, что значение глобальной переменной изменяется между двумя доступами. Как правило, в отличие от прямого доступа к переменной, вызов функции всегда является для вас точкой управления.

0 голосов
/ 07 апреля 2019

Попробуйте это:

import lang_module
from mock import patch
@patch('languages.list', ['EN', 'ES', 'DE'])
class TestLanguages():

    def test_length(self):
        assert 3 == lang_module.get_length()

    def test_contains_lang(self):
       assert lang_module.contains_lang('EN')
...