假设我想断言 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 ....
谢谢。很抱歉问题很长。我真的很想擅长编写单元测试。
最佳答案
我必须说,在这个特定的用例中,我认为修补/模拟不是最好的选择......
对于这个单元测试,我将在文件系统中创建一个结构,在磁盘中的该结构上运行算法并检查不同的结果(所有这些都没有模拟操作系统或 shutil)。
通常我倾向于在外部设置困难或缓慢(即:可能必须设置一些外部数据库)或者当它会停止测试(即:打开一些对话框)或者我想做的时候使用补丁一些难以通过其他方式检查的内容(例如计算是否实际访问了某些缓存)。
除此之外,太多的补丁/模拟给我的印象是你的设计有问题(这不是在考虑单元测试的情况下完成的),因此,将它分解成更小的 block 进行测试可能会有所帮助。 ..
关于python - 使用模拟对象的困境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10288918/