2014-03-01 224 views
2

我正在困扰Python的模拟测试方法。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

+0

'__addon__'从哪里来?如果你嘲笑了那个对象,你需要确保你为getSetting()调用设置了一个返回值。 –

回答

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',第二CAL会产生'42'

+0

感谢Martijn的工作。它仍然让我头疼,因为它感觉我正在改变一个实例,它以某种方式改变了类定义本身。 – powlo