[英]How to mock object attributes and complex fields and methods?
I have a following function which needs to be unit tested. 我有以下功能,需要进行单元测试。
def read_all_fields(all_fields_sheet):
entries = []
for 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, my all_fields_sheet is a sheet returned by xlrd module(Used to read Excel file). 现在,我的all_fields_sheet是xlrd模块返回的工作表(用于读取Excel文件)。
So, basically I need to mock for following attributes nrows cell 所以,基本上我需要模拟以下属性来增加单元格
How should I go abput it? 我应该怎么去消化呢?
Just mock the calls and attributes directly on a mock object; 只需直接在模拟对象上模拟调用和属性即可; adjust to cover your 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 a list to Mock.side_effect
you can control, in order, what calls to .cell()
return. 通过为
Mock.side_effect
分配一个列表,您可以依次控制对.cell()
调用返回的内容。
Afterwards, you can test if the right calls have been made with the various assertion methods. 之后,您可以测试是否使用各种断言方法进行了正确的调用。 You could use the
mock.call()
object to give precise expectations: 您可以使用
mock.call()
对象给出精确的期望值:
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 to match an exact number of calls, directly to mock_sheet.cell
alone. 我在这里使用了
Mock.call_args_list
来匹配确切的呼叫数,直接将mock_sheet.cell
单独匹配到mock_sheet.cell
。
Demo, assuming that your read_all_fields()
function is already defined: 演示,假设您的
read_all_fields()
函数已经定义:
>>> from 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, you could create a function for the mock_sheet.cell.side_effect
attribute, to return values from a 'sheet' you set up up front: 另外,您可以为
mock_sheet.cell.side_effect
属性创建一个函数,以从您之前设置的“工作表”中返回值:
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
is a function, it is called whenever mock_sheet.cell()
is called, with the same arguments. 如果
side_effect
是一个函数,则在调用带有相同参数的mock_sheet.cell()
将调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.