Я только начинаю использовать библиотеку mock Python, чтобы помочь писать более сжатые и изолированные модульные тесты. Моя ситуация в том, что у меня есть класс, который читает данные из довольно волосатого формата, и я хочу протестировать метод в этом классе, который представляет данные в чистом формате .Издевательство над классом
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
на единичном уровне тестирования. Если бы я был экземпляр этого класса, давая ему путь, он будет нарушать rules of unit tests, потому что:
тест не тестовый модуль, если:
- Это касается файловой системы
Итак, я хотел бы иметь возможность исправить метод __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])
Этот код работает, но похоже, что этот тест проходит довольно круто. Есть ли более идиоматический способ исправления конструктора или это правильный способ сделать это? Кроме того, есть ли какой-то запах кода, как в моем классе, так и в тесте, который мне не хватает?
Edit: Чтобы быть ясно, моя проблема заключается в том, что во время инициализации, мой класс делает значительные объемы обработки данных для организации данных, которые будут представлены по методе, как x_coords
. Я хочу знать, что является самым простым способом для исправления всех этих шагов, без необходимости предоставления полного примера ввода. Я хочу только проверить поведение x_coords
в ситуации, когда я управляю данными, которые он использует.
Мой вопрос о том, существует или нет код запах здесь сводится к этому вопросу:
я уверен, что это было бы легче, если бы я реорганизовать, чтобы x_coords
быть автономным функция, которая принимает holds_data
в качестве параметра , Если «легче тестировать == лучший дизайн», это будет путь. Однако для этого потребуется функция x_coords
, чтобы узнать больше о внутренних элементах holds_data
, с которыми мне было бы удобно. Где я должен сделать компромисс? Чистый код или чистые тесты?
Да, это то, что я искал. Спасибо. – Wilduck
3 года спустя, но могут быть полезны для кого-то: после того, как вы получили объект 'mock', вы можете просто сделать' hold_data.x_coords (mock) 'и сохранить беспорядок при назначении методам вещам. – Holloway