Модульное тестирование метода, использующего менеджер контекста - PullRequest
0 голосов
/ 02 октября 2018

У меня есть метод, который я хотел бы для модульного тестирования.Метод ожидает путь к файлу, который затем открывается - с помощью диспетчера контекста - для анализа значения, которое затем возвращается, если оно присутствует, достаточно просто.

@staticmethod
def read_in_target_language(file_path):
    """
    .. note:: Language code attributes/values can occur
    on either the first or the second line of bilingual.
    """
    with codecs.open(file_path, 'r', encoding='utf-8') as source:
        line_1, line_2 = next(source), next(source)
        get_line_1 = re.search(
            '(target-language=")(.+?)(")', line_1, re.IGNORECASE)
        get_line_2 = re.search(
            '(target-language=")(.+?)(")', line_2, re.IGNORECASE)
        if get_line_1 is not None:
            return get_line_1.group(2)
        else:
            return get_line_2.group(2)

Я хочу избежать тестирования на внешниефайлы - по понятным причинам - и не хотят создавать временные файлы.Кроме того, я не могу использовать StringIO в этом случае.

Как я могу насмехаться над объектом file_path в моем модульном тесте?В конечном счете, мне нужно создать фиктивный путь, содержащий разные значения.Любая помощь с благодарностью получена.

1 Ответ

0 голосов
/ 03 октября 2018

(Отказ от ответственности: я не говорю на Python, поэтому я могу ошибаться в деталях)

Я предлагаю вам вместо этого высмеивать codecs.Заставьте метод макета open вернуть объект с тестовыми данными, которые будут возвращены из вызовов read.Это может включать создание другого фиктивного объекта для возвращаемого значения;Я не знаю, есть ли в Python классы запаса, которые вы могли бы использовать для этой цели вместо этого.

Затем, чтобы действительно включить проверку логики, добавьте параметр к read_in_target_language, который представляет объектэто может взять на себя роль исходного codecs объекта, то есть внедрение зависимости аргументом.Для удобства, я думаю, вы могли бы по умолчанию установить значение codecs.

Я не уверен, насколько далеко зашла типизация Python по утилитам в отношении методов static против экземпляра, но что-то вроде этого должно дать вам общее представление:

def read_in_target_language(file_path, opener=codecs):
    ...
    with opener.open(file_path, 'r', encoding='utf-8') as source:

Если вышеописанное невозможно, вы можете просто добавить слой косвенности:

class CodecsOpener:
    ...
    def open(self, file_path, access, encoding):
        return codecs.open(file_path, access, encoding)

class MockOpener:
    ...
    def __init__(self, open_result):
        self.open_result = open_result

    def open(self, file_path, access, encoding):
        return self.open_result

...

    def read_in_target_language(file_path, opener=CodecsOpener()):
        ...
        with opener.open(file_path, 'r', encoding='utf-8') as source:
            ...

...

    def test():
        readable_data = ...
        opener = MockOpener(readable_data)
        result = <class>.read_in_target_language('whatever', opener)
        <check result>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...