How to test or mock “if __name__ == '__main__'” contents

前端 未结 7 703
無奈伤痛
無奈伤痛 2020-12-07 20:07

Say I have a module with the following:

def main():
    pass

if __name__ == \"__main__\":
    main()

I want to write a unit test for the b

7条回答
  •  无人及你
    2020-12-07 20:18

    Python 3 solution:

    import os
    from importlib.machinery import SourceFileLoader
    from importlib.util import spec_from_loader, module_from_spec
    from importlib import reload
    from unittest import TestCase
    from unittest.mock import MagicMock, patch
        
    
    class TestIfNameEqMain(TestCase):
        def test_name_eq_main(self):
            loader = SourceFileLoader('__main__',
                                      os.path.join(os.path.dirname(os.path.dirname(__file__)),
                                                   '__main__.py'))
            with self.assertRaises(SystemExit) as e:
                loader.exec_module(module_from_spec(spec_from_loader(loader.name, loader)))
    

    Using the alternative solution of defining your own little function:

    # module.py
    def main():
        if __name__ == '__main__':
            return 'sweet'
        return 'child of mine'
    

    You can test with:

    # Override the `__name__` value in your module to '__main__'
    with patch('module_name.__name__', '__main__'):
        import module_name
        self.assertEqual(module_name.main(), 'sweet')
    
    with patch('module_name.__name__', 'anything else'):
        reload(module_name)
        del module_name
        import module_name
        self.assertEqual(module_name.main(), 'child of mine')
    

提交回复
热议问题