python - How to mock object attributes and complex fields and methods? -


i have following function needs unit tested.

def read_all_fields(all_fields_sheet):     entries = []      row_index in xrange(2, all_fields_sheet.nrows):         d = {'size' : all_fields_sheet.cell(row_index,0).value,\              'type' : all_fields_sheet.cell(row_index,1).value,\              'hotslide' : all_fields_sheet.cell(row_index,3).value}         entries.append((all_fields_sheet.cell(row_index,2).value,d))      return entries 

now, all_fields_sheet sheet returned xlrd module(used read excel file).

so, need mock following attributes nrows cell

how should go abput it?

just mock calls , attributes directly on mock object; adjust cover test needs:

mock_sheet = magicmock() mock_sheet.nrows = 3  # loop once cells = [     magicmock(value=42),     # row_index, 0     magicmock(value='foo'),  # row_index, 1     magicmock(value='bar'),  # row_index, 3     magicmock(value='spam'), # row_index, 2 ] mock_sheet.cell.side_effect = cells 

by assigning list mock.side_effect can control, in order, calls .cell() return.

afterwards, can test if right calls have been made various assertion methods. use mock.call() object give precise expectations:

result = read_all_fields(mock_sheet) self.assertequal(     result,      [('spam', {'size': 42, 'type': 'foo', 'hotslide': 'bar'})] )  self.assertequal(     mock_sheet.cell.call_args_list,     [call(2, 0), call(2, 1), call(2, 3), call(2, 2)]) 

i used mock.call_args_list here match exact number of calls, directly mock_sheet.cell alone.

demo, assuming read_all_fields() function defined:

>>> unittest.mock import magicmock, call >>> mock_sheet = magicmock() >>> mock_sheet.nrows = 3  # loop once >>> cells = [ ...     magicmock(value=42),     # row_index, 0 ...     magicmock(value='foo'),  # row_index, 1 ...     magicmock(value='bar'),  # row_index, 3 ...     magicmock(value='spam'), # row_index, 2 ... ] >>> mock_sheet.cell.side_effect = cells >>> result = read_all_fields(mock_sheet) >>> result == [('spam', {'size': 42, 'type': 'foo', 'hotslide': 'bar'})] true >>> mock_sheet.cell.call_args_list == [call(2, 0), call(2, 1), call(2, 3), call(2, 2)] true 

alternatively, create function mock_sheet.cell.side_effect attribute, return values 'sheet' set up front:

cells = [[42, 'foo', 'spam', 'bar']]  # 1 row def mock_cells(row, cell):     return magicmock(value=cells[row - 2][cell]) mock_sheet.cell.side_effect = mock_cells 

when side_effect function, called whenever mock_sheet.cell() called, same arguments.


Comments

Popular posts from this blog

magento2 - Magento 2 admin grid add filter to collection -

Android volley - avoid multiple requests of the same kind to the server? -

Combining PHP Registration and Login into one class with multiple functions in one PHP file -