【问题标题】:Fake out module including attributes包含属性的伪造模块
【发布时间】:2013-05-20 12:39:14
【问题描述】:

作为一个单元测试,我希望能够以编程方式测试在一堆 GUI 屏幕中定义的导入是否有意义。我不想执行任何操作,只是

import main_screen

并查看在导入链中是否有任何问题。我已经使用 sys.modules 技巧了:

import my_fake_module
sys.modules['module_i_want_to_fake'] = my_fake_module

效果很好,直到有什么效果:

from module_i_want_to_fake import real_attribute

然后我当然会得到一个 ImportError,除非我向 my_fake_module 添加一个存根的方法/类,但是有太多的方法无法实现。

有什么方法可以挂钩来自 my_fake_module 的导入,以便它们始终成功?同样,他们不需要做任何事情。我敢打赌有一个简单的方法,但它现在正在逃避我......

【问题讨论】:

  • 我不确定您所说的 anything falls over´ but does mymod = __import__("module_name")` 是什么意思?你可以打电话给reload(mymod),你可以对变量进行测试吗?您还可以自己修改__import__ 函数/方法,并进行回退和错误处理,甚至动态创建虚拟函数/存根。
  • “任何东西都掉了”我只是说看看是否有损坏的引用、错别字等,但我可能会扩展它以查找孤儿和其他一些分析。是的,覆盖__import__ 听起来不错,但到目前为止我无法弄清楚或用谷歌搜索它。也许我需要通过创建一个新的导入器来做 PEP302 的事情。

标签: python unit-testing python-2.7


【解决方案1】:

一种选择是创建一个自定义的FakeModule 类来处理__getattr__ 并分发适当的存根函数/值:

>>> class FakeModule:
...     def __getattr__(self, name):
...         print name
...         return name
...
>>> sys.modules['fakeModule'] = FakeModule()
>>> from fakeModule import something
__path__
something
something
>>> something
'something'

实际代码需要比上面的快速概念证明多一点思考,可能会返回一个 lambda,因此您至少可以执行导入的值。

你可能想做这样的事情:

from functools import wraps

class FakeModule(object):
    def __init__(self):
        self.module = __import__("module_to_fake")

    @staticmethod
    def __testWrapper(fn):
        @wraps(fn)
        def wrapped(*args):
            print "%s called with args %s" % (fn.__name__, args)
            result = fn(*args)
            print "    Result was %s" % (result,)
            return result
        return wrapped

    def __getattr__(self, name):
        try:
            result = getattr(module, name)
        except AttributeError:
            print "tried to get %s, which does not exist" % name
            result = None

        if hasattr(result, "__call__"):
            result = self.__testWrapper(result)

        return result

【讨论】:

  • 是的,有点。我认为我理解的关键是我需要了解我必须将模块包装在一个类中才能覆盖魔术方法。我所要做的就是按名称颠覆该包中的几个子模块,因此它们最终在单元测试上下文中工作。另见:stackoverflow.com/a/2447383/455916
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 2015-11-01
  • 2014-09-03
  • 2015-02-12
  • 2017-06-07
相关资源
最近更新 更多