假设我想声明result
采用特定格式,我可以将返回值设置为(True, 'Success')
def batch_move(self, *args, **kwargs):
'''
Move a batch of files to its respective destinations.
Return type: tuple (boolean, message)
T/F , 'string' / str(exception)
'''
srcs= kwargs.get('srcs', None)
dests = kwargs.get('dests', None)
try:
if srcs and dests:
# map srcs and dests into dictionary (srcs --> keys, dests --> values)
src_dest= dict(zip(srcs, dests))
for src, dest in src_dest:
if os.path.exists(src):
if os.path.exists(dest):
shutil.rmtree(dest)
shutil.move(src, dest) # either way we will proceed to move
else:
return (False, '%s does not exist!' % src)
return (True, 'Success!')
else:
return (False, 'Something gone wrong with those kwargs...')
except Exception as e:
return (False, e)
要前往return (True, 'Success!')
os.path.exists
作为返回值的修补程序True
。但是在一个单元测试中,我想跳过这个,如何修补os.path.exists
?if os.path.exists(dest): # I want to skip this shutil.rmtree(dest)
如何修补shutil.move(src, dest)
?我只是给True
所以它不会产生错误吗?如果我想要它失败并且发现异常怎么办?我该如何模拟呢? (我不会总是知道要捕获哪个例外,使用Exception as e
的主要原因)。
如果我实际传递了这个函数,它是否真的意味着没有捕到异常并且它经历了每一行?或者是因为我设置了'mock_object.return_value =(True,'Success!')?
我只使用两个依赖项,是否需要修补所有外部依赖项,如(os,sys,math,datetime)?或者,如果我的函数正在使用其他函数(已重构)
def f1(*args, **kwargs): f2(..) # use math, plot, datetime f3(..) # use math and datetime f4(..) # use datetime ....
感谢。对不起,很长的问题。我真的很想擅长编写单元测试。
答案 0 :(得分:1)
我必须说,在这个特定的用例中,我认为修补/嘲笑不是最好的替代方案......
对于这个单元测试,我在文件系统中创建一个结构,在磁盘中的该结构上运行算法并检查不同的结果(所有这些都没有模拟os或shutil)。
通常我倾向于使用补丁,主要是在外部设置困难或缓慢时(即:可能需要设置一些外部数据库)或者当它停止测试时(即:打开一些对话框)或我想做什么时否则很难检查的东西(比如实际访问某些缓存的计数)。
除此之外,修补/嘲讽太多让我觉得你的设计存在问题(没有考虑到单元测试),因此,在较小的块中进行测试可能有所帮助。 ..