Python unittest mock ...模拟一个模块语句

时间:2014-03-01 15:08:04

标签: python unit-testing python-2.7 mocking xbmc

我正在疯狂地了解python的模拟测试方法。

我想对this file进行一些嘲弄。

由于软件包xbmc,xbmcaddon和xbmcgui无法在普通的python环境中导入,我设法将它们模仿出来:

class XBMCTestCase(unittest.TestCase):    
    def setUp(self):
        #Mock up any calls to modules that cannot be imported
        self.xbmc = Mock()
        self.xbmcgui = Mock()
        self.xbmcaddon = Mock()

        modules = {
            'xbmc' : self.xbmc,
            'xbmcgui': self.xbmcgui,
            'xbmcaddon': self.xbmcaddon
            }
        self.module_patcher = patch.dict('sys.modules', modules) #@UndefinedVariable
        self.module_patcher.start()

在行动here中查看。

因此,当我导入setlocation.py时,我收到如下错误:

  File "/home/paulo/workspace/weather.metoffice/src/metoffice/utils/utilities.py", line 21, in <module>
    CACHE_FOLDER = os.path.join(ADDON_DATA_PATH, 'cache')
  File "/usr/lib/python2.7/posixpath.py", line 78, in join
    path +=  b
TypeError: unsupported operand type(s) for +=: 'Mock' and 'str'

即使我嘲笑'metoffice.utils'(通过将其添加到设置中创建的补丁中的模块列表),我在setlocation.py

中也收到了类似的错误
  File "/home/paulo/workspace/weather.metoffice/src/metoffice/setlocation.py", line 32, in <module>
    GEOIP_PROVIDER = int(__addon__.getSetting('GeoIPProvider'))
TypeError: int() argument must be a string or a number, not 'Mock'

所以我需要__addon__.getSetting()来返回一个字符串。

有什么想法吗?

所有尝试都失败了,但我认为我并没有完全掌握模拟包的功能。

注意我在Python 2.7.3上使用mock 1.0.1

1 个答案:

答案 0 :(得分:1)

你需要告诉你的模拟返回什么。 __addon__值是xbmcaddon.Addon()调用的结果,因此您可以使用以下命令访问该模拟对象:

addon = self.xbmcaddon.Addon.return_value

因为.return_value会为您提供调用Mock的实际Addon()对象。

现在,您可以告诉Mock对象在调用getSetting()方法时要返回的内容;这里提供了两个值,因此您可以使用side_effect设置要返回的值序列:

addon.getSetting.side_effect = ['some_api_key', '42']

第一次调用__addon__.getSetting()会产生第一个值'some_api_key',第二个调用将产生'42'