Python 使用mock模拟导入的模块以测试挂架控制器功能
我一直在关注一个问题,就是如何实现mock来测试一个挂架控制器功能 我尝试测试的特定功能可以在这里找到: 目标: 我只是想模拟它调用的函数,这样我就可以确认它最终调用了get_完备性 问题: 我可以模拟(好),(稳定)(延迟),(失败),(分支)(缓存)很好。但是当涉及到g.buildapi_cache.get_builds_for_revision时,我似乎无法正确地模拟它,每次调用revision(),它都失败了 g实际上是pylons.app_globals,并导入到selfservice.py控制器中,如下所示:“从pylons导入app_globals作为g” 测试: 我正在使用python解释器来测试所有这些。以下是我正在尝试的两种实现:和 总而言之,这里是解释器中的完整运行,包括对Python 使用mock模拟导入的模块以测试挂架控制器功能,python,mocking,pyramid,pylons,python-mock,Python,Mocking,Pyramid,Pylons,Python Mock,我一直在关注一个问题,就是如何实现mock来测试一个挂架控制器功能 我尝试测试的特定功能可以在这里找到: 目标: 我只是想模拟它调用的函数,这样我就可以确认它最终调用了get_完备性 问题: 我可以模拟(好),(稳定)(延迟),(失败),(分支)(缓存)很好。但是当涉及到g.buildapi_cache.get_builds_for_revision时,我似乎无法正确地模拟它,每次调用revision(),它都失败了 g实际上是pylons.app_globals,并导入到selfservice
>>来自buildapi.controllers.selfservice导入SelfserveController
>>>从mock导入补丁,mock
>>>s=SelfserveController()
>>>s._ok=Mock(name=''u ok')
>>>s.(获取)稳定(延迟=模拟)(返回)值=180)
>>>s._分支_缓存=Mock()
>>>s._分支_缓存={'try':无}
>>>s._failed=Mock(返回_value=“failed”)
>>>使用补丁('buildapi.controllers.selfservice.g.buildapi\u cache.get\u builds\u for\u revision')作为get\u builds\u for\u revision:
... 获取修订版的版本。返回值=['baz','bang']
... 结果=修订('try','bar')
...
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/mock.py”,第1252行,输入__
self.target=self.getter()
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/mock.py”,第1414行,在
getter=lambda:\导入器(目标)
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/mock.py”,第1102行,在
thing=\u dot\u查找(thing、comp、import\u路径)
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/mock.py”,第1089行,在dot\u查找中
return getattr(事物、公司)
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/paste/registry.py”,第137行,在__
返回getattr(self.\u current\u obj(),attr)
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/paste/registry.py”,第197行,位于当前对象中
'线程''%self.\\\\\\\\\\\\\\\\\\\\\\'
TypeError:没有为此线程注册对象(名称:app_globals)
这是给你的
>>来自buildapi.controllers.selfservice导入SelfserveController
>>>从mock导入补丁,mock
>>>s=SelfserveController()
>>>s._ok=Mock(name=''u ok')
>>>s.(获取)稳定(延迟=模拟)(返回)值=180)
>>>s._分支_缓存=Mock()
>>>s._分支_缓存={'try':无}
>>>s._failed=Mock(返回_value=“failed”)
>>>g=Mock()
>>>g.buildapi\u cache=Mock(name='buildapi\u cache')
>>>g.buildapi_cache.get_builds_for_revision=Mock(name='get_builds_for_revision',返回_值=['baz','bang'])
>>>美国修订版('try','bar')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“buildapi/controllers/selfservice.py”,第217行,修订版
作业\u项=g.buildapi\u缓存。获取\u版本的\u版本(分支,版本)
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/paste/registry.py”,第137行,在__
返回getattr(self.\u current\u obj(),attr)
文件“/Users/jzeller/buildapi test/lib/python2.7/site packages/paste/registry.py”,第197行,位于当前对象中
'线程''%self.\\\\\\\\\\\\\\\\\\\\\\'
TypeError:没有为此线程注册对象(名称:app_globals)
这与我尝试运行修订版时遇到的错误相同。每次它都会出错,因为我试图模拟这个app_globals模块失败了,或者看起来是这样。我真的不知道还有什么别的办法可以试试有人有什么想法吗?
以下是一些更好的细节:
- 下面是我尝试使用的函数,它位于我正在实例化的类中:
- 如果没有初始化的挂架环境,控制器不能用作独立对象
使用Pylons提供的用于测试的功能,可以从测试控制器的所有样板代码中节省您的时间
我建议您将TestController类与nosetests结合使用,如中所示
特别是对于您的代码,我认为Pylons对待私有方法(以u开头)的方式与对待公共方法的方式不同,因为公共方法是在请求的上下文中运行的
>>> from buildapi.controllers.selfserve import SelfserveController
>>> from mock import patch, Mock
>>> s = SelfserveController()
>>> s._ok = Mock(name='_ok')
>>> s._get_stable_delay = Mock(return_value=180)
>>> s._branches_cache = Mock()
>>> s._branches_cache = {'try': None}
>>> s._failed = Mock(return_value="Failed")
>>> with patch('buildapi.controllers.selfserve.g.buildapi_cache.get_builds_for_revision') as get_builds_for_revision:
... get_builds_for_revision.return_value = ['baz', 'bang']
... result = revision('try', 'bar')
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/mock.py", line 1252, in __enter__
self.target = self.getter()
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/mock.py", line 1414, in <lambda>
getter = lambda: _importer(target)
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/mock.py", line 1102, in _importer
thing = _dot_lookup(thing, comp, import_path)
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/mock.py", line 1089, in _dot_lookup
return getattr(thing, comp)
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/paste/registry.py", line 137, in __getattr__
return getattr(self._current_obj(), attr)
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/paste/registry.py", line 197, in _current_obj
'thread' % self.____name__)
TypeError: No object (name: app_globals) has been registered for this thread
>>> from buildapi.controllers.selfserve import SelfserveController
>>> from mock import patch, Mock
>>> s = SelfserveController()
>>> s._ok = Mock(name='_ok')
>>> s._get_stable_delay = Mock(return_value=180)
>>> s._branches_cache = Mock()
>>> s._branches_cache = {'try': None}
>>> s._failed = Mock(return_value="Failed")
>>> g = Mock()
>>> g.buildapi_cache = Mock(name='buildapi_cache')
>>> g.buildapi_cache.get_builds_for_revision = Mock(name='get_builds_for_revision', return_value=['baz', 'bang'])
>>> s.revision('try', 'bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "buildapi/controllers/selfserve.py", line 217, in revision
job_items = g.buildapi_cache.get_builds_for_revision(branch, revision)
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/paste/registry.py", line 137, in __getattr__
return getattr(self._current_obj(), attr)
File "/Users/jzeller/buildapi-test/lib/python2.7/site-packages/paste/registry.py", line 197, in _current_obj
'thread' % self.____name__)
TypeError: No object (name: app_globals) has been registered for this thread