简体   繁体   中英

How to mock in a python unittest a library not installed locally?

I am trying to test using unittest a python 3.6 script that starts with ( my_app.py ):

import sys
from awsglue.utils import getResolvedOptions

args = getResolvedOptions(sys.argv, ['opt1', 'opt2', 'opt3'])
opt1 = args['opt1']
opt2 = args['opt2']
opt3 = args['opt3']
....

so in my test I did something like:

import unittest
import datetime
from mock import patch
import my_app

class TestMyApp(unittest.TestCase):

    @patch('awsglue.utils.getResolvedOptions')
    def test_mock_stubs(self, patch_opts):
        patch_opts.return_value = {}
        ....

but the test soon fails at import my_app with:

ModuleNotFoundError: No module named 'awsglue'

as there is not awsglue locally installed. How can I test a module that import a not locally installed library and also mock it in my test?

You'll need to mock the imported module before the import for my_app happens. patch won't work here, because patch imports the module in order to patch it. And in this case, that import itself would cause an error.

To do this the simplest way is to trick python into thinking that awsglue is already imported. You can do that by putting your mock directly in the sys.modules dictionary. After this you can do the my_app import.

import unittest
import sys
from unittest import mock


class TestMyApp(unittest.TestCase):

    def test_mock_stubs(self):
        # mock the module
        mocked_awsglue = mock.MagicMock()
        # mock the import by hacking sys.modules
        sys.modules['awsglue.utils'] = mocked_awsglue
        mocked_awsglue.getResolvedOptions.return_value = {}

        # move the import here to make sure that the mocks are setup before it's imported
        import my_app

You can move the import hack part to a setup fixture method.

However I would suggest just installing the package. The import hack can be very difficult to maintain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM