Python单元测试模拟...模拟一个模块声明

3

我很难理解Python的模拟测试方法。

我想在这个文件上进行一些模拟测试。

由于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()

这里查看示例。

因此,当我导入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'模块mock出来(通过在安装设置时将其添加到补丁的模块列表中),我在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()返回一个字符串。

有什么想法吗?

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

注意,我使用的是Python 2.7.3和mock 1.0.1


__addon__ 是从哪里来的?如果你已经模拟出那个对象,你需要确保为 getSetting() 调用设置返回值。 - Martijn Pieters
1个回答

1
你需要告诉你的模拟对象返回什么。 __addon__ 值是通过调用 xbmcaddon.Addon() 获得的结果,因此你可以使用以下代码访问该模拟对象:
addon = self.xbmcaddon.Addon.return_value

因为.return_value给出了调用Addon()将返回的实际Mock对象。
现在,您可以告诉Mock对象,在调用getSetting()方法时返回什么值;这里需要提供两个值,所以您可以使用side_effect 来设置要返回的值序列:
addon.getSetting.side_effect = ['some_api_key', '42']

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


谢谢Martijn,这个方法很有效。但是我还是感到有些困惑,因为它似乎在对实例进行更改的同时也改变了类定义本身。 - powlo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接