Python 如何模拟不存在模块的层次结构?

Python 如何模拟不存在模块的层次结构?,python,mocking,python-mock,Python,Mocking,Python Mock,假设我们有一个只存在于生产阶段的模块系统。在测试时,这些模块不存在。但我仍然希望为使用这些模块的代码编写测试。我们还假设我知道如何模拟这些模块中所有必要的对象。问题是:如何方便地将模块存根添加到当前层次结构中 这里有一个小例子。我要测试的功能放在一个名为actual.py的文件中: actual.py: def coolfunc(): from level1.level2.level3_1 import thing1 from level1.level2.level3_2 impor

假设我们有一个只存在于生产阶段的模块系统。在测试时,这些模块不存在。但我仍然希望为使用这些模块的代码编写测试。我们还假设我知道如何模拟这些模块中所有必要的对象。问题是:如何方便地将模块存根添加到当前层次结构中

这里有一个小例子。我要测试的功能放在一个名为
actual.py的文件中:

actual.py:


def coolfunc():
  from level1.level2.level3_1 import thing1
  from level1.level2.level3_2 import thing2
  do_something(thing1)
  do_something_else(thing2)
在我的测试套件中,我已经拥有了我所需要的一切:我有
thing1\u mock
thing2\u mock
。我还有一个测试功能。我需要的是将
level1.level2…
添加到当前模块系统中。像这样:

tests.py

import sys
import actual

class SomeTestCase(TestCase):
  thing1_mock = mock1()
  thing2_mock = mock2()

  def setUp(self):
    sys.modules['level1'] = what should I do here?

  @patch('level1.level2.level3_1.thing1', thing1_mock)
  @patch('level1.level2.level3_1.thing1', thing2_mock)
  def test_some_case(self):
    actual.coolfunc()

我知道我可以用包含另一个对象的对象替换
sys.modules['level1']
,以此类推。但对我来说似乎有很多代码。我认为一定有更简单、更漂亮的解决方案。我就是找不到它。

所以,没有人帮我解决问题,我决定自己解决。是一个名为
subrogate
的微库,它允许为不存在的模块创建存根

Lib可以与
mock
一起使用,如下所示:

from surrogate import surrogate
from mock import patch

@surrogate('this.module.doesnt.exist')
@patch('this.module.doesnt.exist', whatever)
def test_something():
    from this.module.doesnt import exist
    do_something()
首先,
@subrogate
decorator为不存在的模块创建存根,然后,
@patch
decorator可以修改它们。正如
@patch
@subrogate
装饰符可以“复数”使用,因此可以保留多个模块路径。所有存根仅在修饰函数的生存期内存在


如果有人使用了这个库,那就太好了:)

如果属性不存在,你可以在方法中使用“create”参数,强制创建属性。

这对模块不起作用,这就是问题所在。你为什么不创建一个pip库?这太棒了!