【问题标题】:implement decorator who will be substitute one class with another implementation实现装饰器,将一个类替换为另一个实现
【发布时间】:2014-08-26 09:01:21
【问题描述】:

我需要的是这样的:

def method():
  my_var = module.Class1()  #actually calling Class1 constructor
  ...

我需要实现装饰器,一旦类定义与另一个类定义发生变化,就像这样:

@substitute(module.class1 = new_module.class2)
def method():
  my_var = module.Class1()  #actually calling new_module.class2 constructor
  ...

能否请您给我一些提示。

【问题讨论】:

  • 你在使用线程吗?
  • 可能是,但我认为可以避免。我需要它来测试。用假实现替换类,因为我们没有对项目进行适当的依赖注入
  • 对,所以你是在模拟测试;为此使用mock 库。
  • 模拟仍然可以帮助解决这个问题;您可以模拟解析驱动程序的方法或驱动程序对象本身。所有 Python 都是动态的,您可以修补的内容几乎没有限制。

标签: python python-2.7 decorator


【解决方案1】:

您正在尝试做的事情称为模拟。使用mock library 执行此操作;该库是 Python 3.4 及更高版本的一部分 unittest.mock

使用mock,您可以仅在测试时修补原始功能

try:
    from unittest.mock import patch
except ImportError:
    # Python < 3.4
    from mock import patch

with patch('module.class1') as class1_mock:
    mocked_instance = class1_mock.return_value
    mocked_instance.method_to_be_called.return_value = 'Test return value'

    method()

    mocked_instance.method_to_be_called.assert_called_with('Foo', 'bar')

以上在with 块期间模拟了class1,之后撤消补丁。该补丁将module.class1 替换为Mock 对象,您也可以通过class1_mock 访问该对象。上面的例子设置method_to_be_called返回一个被操纵的测试返回值,测试后验证调用签名。

【讨论】:

  • 谢谢,我会看看它是如何工作的。因为这个例子似乎和我需要的一样。购买方式,在python 2.7中可用吗?
  • @Ph0en1x:不,您必须将其安装为测试依赖项。我的项目通常在setup.py 中将这些列为额外内容;以extras_require={'testing': ['coverage', 'mock', 'nose']} 为例。
猜你喜欢
  • 1970-01-01
  • 2021-07-05
  • 2019-12-22
  • 2021-01-14
  • 1970-01-01
  • 2020-11-02
  • 2013-10-28
  • 2020-11-05
  • 2018-11-11
相关资源
最近更新 更多