【发布时间】:2021-08-21 18:12:37
【问题描述】:
我有两个课程A 和B。我想测试A 的函数foo_a。使用一些业务逻辑,foo_a 创建两个可能的 B 实例(具有不同的参数)并调用函数 foo_b 的 B:
class A:
def foo_a(self, *args, **kwargs):
# some code above
if condition_1:
foo_b_result = B(**arguments_1).foo_b()
else:
foo_b_result = B(**arguments_2).foo_b()
# some code below that returns foo_b_result + other objects independent of foo_b_result
问题在于foo_b 是一个调用API 和其他东西的复杂函数。我不想在这个单元测试中模拟 API,以便foo_b 返回适当的输出,事实上,foo_b 已经在我的类B 的单元测试集中的其他地方进行了测试。因此,在这种情况下,我更关心arguments_1 和arguments_2 的正确性,而不是foo_b_result 的正确性。因此,如果我可以模拟foo_b 会很好,这样它返回的输出可以很容易地显示foo_b 是否已被B 的正确实例调用。例如,foo_b 可以返回 arguments_1 或 arguments_2。
在这种情况下,也许还有另一种更好的单元测试方法foo_a,欢迎提出任何想法。
更新:另一种方法是创建一个以condition_1 为输入并返回arguments_1 或arguments_2 的新函数(此函数可以轻松测试)。然后我会模拟 foo_b 以便它总是返回相同的值(例如 0)。但是,知道是否可以模拟 foo_b 以便它根据 arguments_1 或 arguments_2 返回值会很有趣。
【问题讨论】:
-
你想模拟
foo,具体是什么意思?你的意思是你想用测试替身替换MyClass实例? -
刚刚编辑了问题。更清晰?
-
并非如此。如果你正在测试
MyClass,你不应该嘲笑它的任何部分。如果您正在测试 使用MyClass的东西,为什么不通过它,例如MyClass(a=0),其foo方法会根据需要返回0? -
"显示
foo_b是否已被B的正确实例调用" - 不,您需要显示它是否已被调用 on i>B的正确实例,这实际上只是意味着B的调用方式。您可以在例如查看如何模拟课程。 stackoverflow.com/a/38199345/3001761,然后您可以断言B的模拟是用什么调用的。对于这种情况,您不需要将真实行为(“它根据arguments_1或arguments_2返回值”)放入测试替身中。 -
Mocks 有很多方法来断言交互:docs.python.org/3/library/…
标签: python-3.x mocking