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
Post a Comment