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