begin = datetime.strptime('00:01:00.000', '%H:%M:%S.%f')
end = datetime.strptime('00:01:00.002', '%H:%M:%S.%f')
duration = begin - end
duration.total_seconds() // duration.seconds只计算秒的部分,duration.microseconds只计算毫秒的部分。计算时间差使用total_seconds
mock = MagicMock()
dir(mock)
# ['assert_any_call', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'method_calls', 'mock_add_spec', 'mock_calls', reset_mock', 'return_value', 'side_effect']
# 然后我们调用三个不存在的属性
mock.q
mock.w
mock.e
# 再来看看
# 注意 mock 自动创建增加了 q, w, e 方法
dir(mock)
# ['assert_any_call', 'assert_called_once_with', 'assert_called_with', 'assert_has_calls', 'attach_mock', 'call_args', 'call_args_list', 'call_count', 'called', 'configure_mock', 'e', 'method_calls', 'mock_add_spec', 'mock_calls', 'q', 'reset_mock', 'return_value', 'side_effect', 'w']
我们可以使用 spec 来显示的指定那些方法和属性是可 mock 的。class SpecClass:
attr1 = None
attr2 = None
mock = MagicMock(spec=SpecClass)
print(mock.attr1)
# <MagicMock name='mock.attr1' id='4589618064'>
# 尝试调用未指定的属性时就会抛出 AttributeError
mock.attr3
# Traceback (most recent call last):
# File "", line 1, in
# File "/Users/laisky/.pyenv/versions/3.4.1/lib/python3.4/unittest/mock.py", line 568, in __getattr__
# raise AttributeError("Mock object has no attribute %r" % name)
# AttributeError: Mock object has no attribute 'attr3'
顺带一提 spec_set,和 spec 不同的一点在于 spec_set 传入的是一个实例而不是对象:mock = MagicMock(spec=SpecClass)
# 等效于
mock = MagicMock(spec_set=SpecClass())
如果你只是简单希望只能调用显式 mock 过的方法和属性,又懒得去重复写一遍 spec,可以直接指定 spec=True。