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

mel*_*r55 7 python unit-testing monkeypatching

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

这是简化的模式:

    #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
Run Code Online (Sandbox Code Playgroud)

这是一个补丁示例:

from app.framework.stuff import Stuff

def function_override(self):
  return pass

Stuff.function = function_override
Run Code Online (Sandbox Code Playgroud)

当程序以批处理方式执行时,这种方法效果很好,每次都从头开始旋转。然而,当运行单元测试时,我发现猴子补丁在测试中持续存在,导致意外的行为。

我意识到使用面向对象的继承方法来进行这些重写会好得多,但我继承了这个代码库,并且目前无权重新构建它到那种程度。

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

iva*_*eev 4

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

您的选择是:

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