Monkeypatch 在单元测试中持续存在 python

Monkeypatch persisting across unit tests python

我有一个自定义框架,它为不同的客户端运行不同的代码。我对某些方法进行了 monkeypatched,以便为客户端自定义功能。

这是简化的模式:

    #import monkeypatches here
    if self.config['client'] == 'cool_dudes':
        from app.monkeypatches import Stuff
    if self.config['client'] == 'cool_dudettes':
        from app.monkeypatches import OtherStuff

这是一个示例补丁:

from app.framework.stuff import Stuff

def function_override(self):
  return pass

Stuff.function = function_override

当程序以批处理方式执行时,这工作正常,每次都从头开始旋转。但是,当 运行 跨单元测试时,我发现猴子补丁在整个测试中持续存在,导致意外行为。

我意识到对这些覆盖使用面向对象的继承方法会好得多,但我继承了这个代码库,目前无权将其重新架构到那种程度。

除非正确地重新构建程序,否则如何防止这些猴子补丁在单元测试中持续存在?

模块(包括 app.framework.<whatever>)不会在每次测试时都重新加载。因此,您对它们所做的任何更改都会持续存在。如果您的模块是有状态的,也会发生同样的情况(这就是为什么全局状态不是一个好主意的原因之一,您应该将状态保存在对象中)。

您的选择是:

  • 在需要时撤消猴子补丁,或者
  • 将它们更改为更通用的内容,根据测试 运行 或
  • 自动(半)自动更改
  • (首选)不要重新发明轮子并使用现有的、可管理的、经过时间验证的解决方案来完成你的任务(或者至少,如果它不能完全满足你的要求,你的工作就基于它)。例如。如果您将它们用于模拟,请参阅 How can one mock/stub python module like urllib 。在建议中有 @mock.patch 为特定测试打补丁并在完成后撤消它。

来这里寻找有关 monkeypatching 的信息的任何人都可能想看看 pytestmonkeypatch fixture。它通过在测试功能完成后自动撤消所有修改来避免 OP 的问题。