如何模拟不存在的模块的层次结构? [英] How do I mock the hierarchy of non-existing modules?
问题描述
假设我们有一个仅存在于生产阶段的模块系统.在测试时,这些模块不存在.但我仍然想为使用这些模块的代码编写测试.我们还假设我知道如何从这些模块中模拟所有必要的对象.问题是:我如何方便地将模块存根添加到当前层次结构中?
Let's assume that we have a system of modules that exists only on production stage. At the moment of testing these modules do not exist. But still I would like to write tests for the code that uses those modules. Let's also assume that I know how to mock all the necessary objects from those modules. The question is: how do I conveniently add module stubs into current hierarchy?
这是一个小例子.我要测试的功能放在一个名为 actual.py
的文件中:
Here is a small example. The functionality I want to test is placed in a file called 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_mock
和 thing2_mock
.我也有一个测试功能.我需要的是将 level1.level2...
添加到当前模块系统中.像这样:
In my test suite I already have everything I need: I have thing1_mock
and thing2_mock
. Also I have a testing function. What I need is to add level1.level2...
into current module system. Like this:
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']
替换为包含另一个对象的对象等等.但对我来说似乎有很多代码.我认为必须有更简单和更漂亮的解决方案.我就是找不到.
I know that I can substitute sys.modules['level1']
with an object containing another object and so on. But it seems like a lot of code for me. I assume that there must be much simpler and prettier solution. I just cannot find it.
推荐答案
所以,没有人帮助我解决我的问题,我决定自己解决.这里是一个名为 surrogate
的微型库,它允许为非-现有模块.
So, no one helped me with my problem and I decided to solve it by myself. Here is a micro-lib called surrogate
which allows one to create stubs for non-existing modules.
Lib 可以像这样与 mock
一起使用:
Lib can be used with mock
like this:
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()
首先 @surrogate
装饰器为不存在的模块创建存根,然后 @patch
装饰器可以改变它们.就像 @patch
一样,@surrogate
装饰器可以以复数形式"使用,从而存根多个模块路径.所有存根仅在修饰函数的生命周期内存在.
Firstly @surrogate
decorator creates stubs for non-existing modules, then @patch
decorator can alter them. Just as @patch
, @surrogate
decorators can be used "in plural", thus stubbing more than one module path. All stubs exist only at the lifetime of decorated function.
如果有人使用这个库,那就太好了:)
If anyone gets any use of this lib, that would be great :)
这篇关于如何模拟不存在的模块的层次结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!