How do I make fun of a hierarchy of non-existent modules?

Suppose we have a system of modules that exists only at the production stage. At the time of testing, these modules do not exist. But still, I would like to write tests for code that uses these modules. Suppose also that I know how to mock all the necessary objects from these modules. The question is: how is it convenient for me to add module stubs to the 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 . I also have a testing function. I need to add level1.level2... to the 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 replace sys.modules['level1'] with an object containing another object, and so on. But for me it seems like a lot of code. I suppose it should be much simpler and prettier. I just can't find him.

+7
source share
2 answers

So, no one helped me with my problem, and I decided to solve it myself. Here is a micro-library called surrogate , which allows you to create stubs for non-existent modules.

Lib can be used with mock as follows:

 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, the @surrogate decorator creates stubs for non-existent modules, then the @patch decorator can modify them. Like @patch , @surrogate decorators can be used in the plural, thus wrapping several module paths. All stubs exist only during the life of a decorated function.

If anyone uses this lib, that would be great :)

+11
source

You can use the "create" parameter in the patch () method, which will force the attribute to be created if it does not exist.

0
source

All Articles