1

I have a python module that gets executed as python -m my_package.my_module --arg1 a1 --arg2 a2. Which creates an artifact on the local disk and uploads that artifact to a cloud bucket.

My module essentially looks like this

import argparse

def func():
    # parse args
    # create artifact
    # upload to bucket

func()

I'd like to write a test for this module which I can run from a different script, say test_module.py. I would like to mock the cloud api so nothing gets uploaded, but also provide a set of test command line args to the module.

So far I can do something like this

#test_module.py
from unittest import mock

def test_my_module():
    test_args = # [  test args ]
    with mock.patch.object(sys, 'argv', test_args):
        import my_package.my_module
        # test file is written to local dir

The problem here is that I can't mock the cloud api without first importing my_package.my_module which runs the code in the module and uploads the artifact. And if I do something like this

#test_module.py
from unittest import mock
import my_package.my_module

@mock.patch('my_package.my_module.cloud_client')
def test_my_module():
    # run test

Then the code will execute on the first import statement import my_package.my_module. Is there a solution where I can mock an object before importing the module it's located in?

1 Answer 1

3

Use the idiomatic solution to this exact problem:

import argparse

def func():
    # parse args
    # create artifact
    # upload to bucket

# Ensure this function only runs when this module is being executed as main, not when imported.
if __name__ == '__main__':
    func()

You can find more details here: What does if __name__ == "__main__": do?

After your module is imported (but not run) in the test, you can setup your mock & perform the test.

Sign up to request clarification or add additional context in comments.

1 Comment

Ah yes of course. Thank you. I was so convinced that running the module with the -m flag would change the __name__ variable (something I must have mistakenly thought some time ago) that I didn't even bother testing this. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.