Я создаю класс, который наследуется от NamedTuple
(в частности, для неизменности), который содержит три фрагмента данных в кортеже. Я переопределяю __repr__()
, чтобы обеспечить симпатичное, узнаваемое человеком представление о классе. Тем не менее, пользовательский __repr__
должен сделать несколько дорогих вычислений с данными в кортеже, чтобы обеспечить красивое представление. Таким образом, моя __repr__
функция организована следующим образом:
class MyClass(NamedTuple):
data1: float
data2: MyOtherClass
data3: float
def __repr__():
exp_1 = self.expensive_function1(self.data1, self.data2, self.data3)
exp_2 = self.expensive_function2(self.data1, self.data2, self.data3)
repr_component_1 = MyClass.static_func1(self.data1, exp_1, exp_2)
repr_component_2 = MyClass.static_func2(self.data2, exp_1, exp_2)
repr_component_3 = MyClass.static_func2(self.data3, exp_1, exp_2)
return f"{repr_component_1} {repr_component_2}{repr_component_3}"
Нет проблем с самим кодом. Отлично работает и отлично работает. У меня проблема в том, как эффективно модульный тест статические методы repr_component_1
, repr_component_2
и repr_component_3
.
Если бы MyClass
специально не требовалось быть неизменным, я мог бы бросить exp_1
и exp_2
в атрибуты частного класса и не иметь проблем. Однако MyClass
должен быть неизменным по разным причинам.
Проблема в том, что exp_1
и exp_2
являются специфичными для экземпляра результатами, которые затем вводятся в статические методы в качестве входных данных.
Таким образом, единственный способ проверить это (с pytest
) заключается в следующем:
def test_repr_component_1():
a = MyClass(data1, data2, data3)
exp_1 = a.expensive_function1(self.data1, self.data2, self.data3)
exp_2 = b.expensive_function2(self.data1, self.data2, self.data3)
result1 = MyClass.static_func1(a.data1, exp_1, exp_2)
assert result1 == "expected result"
Тем не менее, это много строк в тестовом сценарии (мой настоящий код содержит более пяти строк)! Конечно, я хочу протестировать многие сценарии. Я уже слышал о настройках и разборках, но не знаю, применимо ли это в этой ситуации.
Хотелось бы подумать о "профессиональном" и питонском способе написания этих модульных тестов.
РЕДАКТИРОВАТЬ: Мне пришло в голову использовать Python 3.7 dataclass
(из-за его способности быть «замороженным»), который позволил бы мне установить exp_1
и exp_2
в качестве частного атрибутов на этапе __post_init__
, но я планирую сделать эту библиотеку общедоступной, и мне не хотелось полагаться на пользователей, имеющих только Python> = 3.7, чтобы она работала.