我正在创建一个继承自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"
但是,每个测试场景有很多行(我的实际代码超过五行)!当然,我希望测试许多场景。我以前听说过设置和拆卸的东西,但我不知道这些东西是否适用于这种情况。
想对编写这些单元测试的“专业”和pythonic方式有一些想法。
编辑:我确实想到使用 Python 3.7 dataclass(因为它能够被“冻结”),这将允许我在步骤期间设置exp_1和exp_2作为私有属性,__post_init__但我计划将其设为公共库并且不想要不得不依赖只有 Python >= 3.7 的用户才能使其工作。