Я только начинаю использовать библиотеку Python mock, чтобы помочь писать более сжатые и изолированные модульные тесты. Моя ситуация в том, что у меня есть класс, который читает данные из довольно волосатого формата, и я хочу протестировать метод в этом классе, который представляет данные в чистом виде Формат.
class holds_data(object):
def __init__(self, path):
"""Pulls complicated data from a file, given by 'path'.
Stores it in a dictionary.
"""
self.data = {}
with open(path) as f:
self.data.update(_parse(f))
def _parse(self, file):
# Some hairy parsing code here
pass
def x_coords(self):
"""The x coordinates from one part of the data
"""
return [point[0] for point in self.data['points']]
Приведенный выше код упрощает то, что у меня есть. На самом деле _parse
- довольно значительный метод, на котором у меня есть тестовое покрытие на функциональном уровне.
Я бы хотел, однако, проверить x_coords
на уровне unit test. Если бы я должен был создать этот класс, указав ему путь, он нарушил бы правила модульных тестов, потому что:
Тест не является unit test, если:
- Он касается файловой системы
Итак, я хотел бы иметь возможность исправить метод __init__
для holds_data
, а затем просто заполнить часть self.data
, необходимую для x_coords
. Что-то вроде:
from mock import patch
with patch('__main__.holds_data.__init__') as init_mock:
init_mock.return_value = None
instance = holds_data()
instance.data = {'points':[(1,1),(2,2),(3,4)]}
assert(instance.x_coords == [1,2,3])
Приведенный выше код работает, но похоже, что этот тест проходит довольно круто. Есть ли более идиоматический способ исправления конструктора или это правильный способ сделать это? Кроме того, есть ли какой-то запах кода, как в моем классе, так и в тесте, который мне не хватает?
Изменить: Чтобы быть ясным, моя проблема заключается в том, что во время инициализации мой класс выполняет значительную обработку данных для организации данных, которые будут представлены с помощью метода типа x_coords
. Я хочу знать, что является самым простым способом для исправления всех этих шагов, без необходимости предоставления полного примера ввода. Я хочу только проверить поведение x_coords
в ситуации, когда я управляю данными, которые он использует.
Мой вопрос о том, есть ли здесь запах кода, сводится к этой проблеме:
Я уверен, что это было бы проще, если бы я реорганизовал, чтобы x_coords
была автономной функцией, которая принимает holds_data
в качестве параметра. Если "легче тестировать == лучший дизайн", это будет путь. Тем не менее, для функции x_coords
требуется знать больше о внутренних элементах holds_data
, с которыми мне обычно было бы удобно. Где я должен сделать компромисс? Чистые коды или чистые тесты?