List method in python returns empty list when we pass magic mock object

Viewed 1219

I have a python code which needs to be run in both Python 2 and 3. In python 2 dict.values() returns list but in python 3 it returns dict_val object. So to make it compatible I have put list(dict.values()). It works fine. But when I am doing a Unit test using python mock there is one error. I am mocking dict.values() and it gives output like this <MagicMock name='mock().values()' id='1099587993168'>, but when I use a list, it makes this empty list. Below is the example.

function file:

class abc():    
 def get_dict(self, key):#i want to mock this as its depends on other method also
    dic = {'key': {'smaplekey': 'samplevalue'}}# its sample - 
    return dic['key']

 def run_method(self, val):
    print val

 def a(self,key):
  print 'before list'
  print self.get_dict(key).values()
  print list(self.get_dict(key).values())
  b = list(self.get_dict(key).values())[0]
  print 'after list'
  self.run_method(b)

test file:

import unittest
from mock import Mock, patch, MagicMock, ANY
import function_file
class TestA(unittest.TestCase):
  @patch('function_file.abc.run_method')
  @patch('function_file.abc.get_dict',MagicMock(return_vlaue={'key': {}}))
  def test_a(self, mock_run_method):
    manager = function_file.abc()
    result = manager.a('key')
    mock_run_method.assert_called_once_with(ANY, create=True)

if __name__ == '__main__':
    unittest.main()

Here list method make magic mock object empty list so it is failing. And below is the python error

 before list
<MagicMock name='mock().values()' id='1099803145040'>
[]
E
======================================================================
ERROR: test_a (__main__.TestA)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "test_manager.py", line 9, in test_a
    result = manager.a('key')
  File "/usr/lib/python2.7/site-packages/abcd/function_file.py", line 13, in a
    b = list(self.get_dict(key).values())[0]
IndexError: list index out of range

----------------------------------------------------------------------
Ran 1 test in 0.004s

FAILED (errors=1)

Here it is going inside the 'a' method and printing also, but list method make mock object empty list. List method should not make mock object empty list

2 Answers

change:

@patch('get_dict',MagicMock(return_vlaue={'key': {}}))

to

@patch('__main__.get_dict', MagicMock(return_value={'key': 1}))

patch target should in the form "module.object_name", you missed namespace, remain mistakes are typos.

Try @patch(__name__ + '.get_dict', MagicMock(return_value={'key': {}) to give a proper target to your mock.

Related