Monkeypatch持续跨越单元测试python

时间:2017-10-23 22:56:56

标签: python unit-testing monkeypatching

我有一个自定义框架,为不同的客户端运行不同的代码。我已经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

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

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

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

2 个答案:

答案 0 :(得分:3)

每次测试都不会重新加载模块,包括x = CreateUser("JohnDoe") 。所以,你所做的任何改变都会持续存在。如果你的模块是有状态的(同样是全局状态不是一个好主意的原因之一,你应该把状态保存在对象中),就会发生同样的情况。

您的选择是:

  • 在需要时撤消猴子补丁,或
  • 将它们更改为更通用的内容,根据测试运行情况自动更改(半),或
  • (首选)不要重新发明轮子,并为您的任务使用现有的,可管理的,久经考验的解决方案(或者至少,如果完全不符合您的要求,则将您的工作基于一个)。例如。如果您使用它们进行模拟,请参阅How can one mock/stub python module like urllib。在建议中有app.framework.<whatever>为特定测试进行修补,并在完成后将其撤消。

答案 1 :(得分:1)

来到这里寻找有关monkeypatching 的信息的任何人都可能想看看pytestmonkeypatch 固定装置。测试功能完成后自动撤消所有修改,避免了OP的问题。