简体   繁体   English

Python 上的不同 unittest.mock 行为 2/3

[英]Different unittest.mock behavior on Python 2/3

I have the unittest that should be compatible with both python 2 and 3. It looks like that:我有应该与 python 2 和 3 兼容的单元测试。它看起来像这样:

def test_getModulePath_BuildInThrowsAnException(self):
    resource = mock.Mock(spec=some.module.SomeClass)
    resource.name = 'BuiltIn'
    resource.parent = resource

    if sys.version_info[0] == 3:  # Python 3
        patched_class = '_frozen_importlib_external.SourceFileLoader'
    else:  # Python 2
        patched_class = 'pkgutil.ImpLoader'

    with mock.patch(patched_class) as loader_mock:
        loader_mock.side_effect = MyException
        try:
            result = MyClass._get_module_path(resource)
            self.assertIsNone(result)
        except MyException as e:
            self.fail(e)

The method i want to test:我要测试的方法:

@classmethod
def _get_module_path(cls, resource):
    ...
    try:
        loader = pkgutil.get_loader(resource.name)
    except MyException as e:
        return None
    ...
    return loader.get_filename() 

The problem is that pkgutil.get_loader() returnes different objects which depends on python version.问题是pkgutil.get_loader()返回不同的对象,这取决于 python 版本。 On Py2 everything is ok, loader raises an error as side_effect, method returnes None and loader_mock.called = True .在 Py2 上一切正常,加载程序引发错误作为副作用,方法返回 None 和loader_mock.called = True But on Py3 loader side_effect doesn't work and method goes to return loader.gt_filename() .但是在 Py3 加载器 side_effect 不起作用并且方法return loader.gt_filename() Any ideas?有任何想法吗? Python version: 2.7.15 and 3.6.3 Python 版本:2.7.15 和 3.6.3

I think, the problem is related with python import system, because the object returned by get_loader is exectly a _frozen_importlib_external.SourceFileLoader , but side_effect is not raised.我认为,问题与 python 导入系统有关,因为 get_loader 返回的get_loader_frozen_importlib_external.SourceFileLoader ,但没有引发side_effect The problem was solved by patching pkgutil.get_loader function, not the return object class:该问题已通过修补pkgutil.get_loader function 而不是返回 object class 解决:

        with mock.patch('pkgutil.get_loader', side_effect=MyException):
            try:
                result = MyClass._get_module_path(resource)
                self.assertIsNone(result)
            except MyException as e:
                self.fail(e)

I hope this will help someone.我希望这会对某人有所帮助。 Thanks.谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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