Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
309 views
in Technique[技术] by (71.8m points)

python - 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?

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)

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()

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 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()

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 :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...