我有一个很难看的功能,我想重构一下。 原理上,该函数需要2个对象,访问几个 这些对象上的属性和方法,将它们组合起来并使用它们 组合结果以实例化结果对象。
看起来像这样:
def ugly(obj_a, obj_b):
a_1 = obj_a.a_1
sub_a_1 = obj_a.get_sub()
r_1 = obj_b.combine(a_1)
if r_1 < 0:
raise ValueError
if not sub_a_1.validate():
raise Exception
return ResultObj(a_1, r_1, sub_a_1.get_matrix(), obj_b.some_other_attribute)
除了在两者上访问许多属性和方法之外 对象以及传递给ResultObj的许多构造函数值。
此功能是单元/集成测试的噩梦。我站在那里 将不得不模拟obj_a和obj_b及其所有方法和 属性。
您对重构此类代码有何建议?理想情况下我 不必改变obj_a和obj_b的实现。
这是在Python中,所以OO和功能设计都有用。
谢谢
答案 0 :(得分:1)
使这种程序代码更易于测试的一种方法是添加&#34; seams&#34;,即将代码分成可以单独运行的单元。很难回答你的问题,因为如果没有实际的代码,很难看到逻辑接缝。
您可以返回ResultObj的参数列表,而不是直接创建一个。这允许您测试过程而不是测试ResultObj。之后ResultObj(*args)
很容易做到{{1}}。但是,你仍然处理很多价值观。
可能你可以有单独的功能分别访问和验证来自A和B的数据,然后返回简单的&#34; flat&#34;由第三个函数组合的数据结构(例如,namedtuple)。
除此之外,重构课程本身对我来说最有意义,尽管你说你宁愿避免它。如果创建A和B对象没有副作用或太多其他依赖项会有所帮助,但这又取决于您的特定代码。
还要考虑&#34;将两个对象组合成一个巨型对象&#34;本质上更多的是集成测试用例,而不是单元测试用例。