Mocking a module import in pytest

前端 未结 1 1648
情话喂你
情话喂你 2020-12-03 08:47

I am writing a pytest plugin that should test software that\'s designed to work inside a set of specific environments.

The software I\'m writing is run inside a bigg

相关标签:
1条回答
  • 2020-12-03 08:54

    pytest provides a fixture for this use-case: monkeypatch.syspath_prepend.

    You may prepend a path to sys.path list of import locations. Write a fake fwlib.py and include it in your tests, appending the directory as necessary. Like the other test modules, it needn't be included with the distribution.

    After playing with this myself, I couldn't actually figure out how to get the fixture to mock module level imports correctly from the library code. By the time the tests run, the library code was already imported and then it is too late to patch.

    However, I can offer a different solution that works: you may inject the name from within conftest.py, which gets imported first. The subsequent import statement within the code under test will just re-use the object already present in sys.modules.

    Package structure:

    $ tree .
    .
    ├── conftest.py
    ├── lib
    │   └── my_lib.py
    └── tests
        └── test_my_lib.py
    
    2 directories, 3 files
    

    Contents of files:

    # conftest.py
    import sys
    
    def fwlib_sum(a, b):
        return a + b
    
    module = type(sys)('fwlib')
    module.sum = fwlib_sum
    sys.modules['fwlib'] = module
    

    library file:

    # lib/my_lib.py
    import fwlib
    
    def fw_sum(a, b):
        return fwlib.sum(a, b)
    

    test file:

    # lib/test_my_lib.py
    import my_lib
    
    def test_sum():
        assert my_lib.fw_sum(1, 2) == 3
    
    0 讨论(0)
提交回复
热议问题