如何模拟不存在的模块的层次结构? [英] How do I mock the hierarchy of non-existing modules?

查看:60
本文介绍了如何模拟不存在的模块的层次结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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_mockthing2_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆