Question

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

Was it helpful?

Solution

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'.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top