I'm having difficuly getting my head around python's mock test methodology.

I want to do some mocking on this file.

Since packages xbmc, xbmcaddon and xbmcgui cannot be imported in a normal python environment I've managed to mock them out like this:

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

See it in action here.

So when I import setlocation.py I get an error like this:

  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'

Even if I mock out 'metoffice.utils' (by adding it to the list of modules in the patch created at setup) I get a similar error in 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'

So I need __addon__.getSetting() to return a string.

Any ideas?

All attempts have failed, but I don't think I have a full grasp of the capabilities of the mock package.

Note I'm on Python 2.7.3 with mock 1.0.1

有帮助吗?

解决方案

You need to tell your mocks what to return. The __addon__ value is the result of a xbmcaddon.Addon() call, so you can get access to that mock object with:

addon = self.xbmcaddon.Addon.return_value

because .return_value gives you the actual Mock object that calling Addon() would return.

Now you can tell that Mock object what to return when the getSetting() method is called; there are two values to provide here, so you could use the side_effect to set a sequence of values to return:

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

where the first call to __addon__.getSetting() will produce the first value 'some_api_key', the second cal will produce '42'.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top