4

假设我想断言它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!')

  1. 补丁作为os.path.exists返回True值。但是在一个单元测试中我想跳过这个,我该如何修补os.path.exists呢?
    if os.path.exists(dest):  # I want to skip this
         shutil.rmtree(dest)
  1. 我该如何修补shutil.move(src, dest)?我只是给True它不产生错误吗?如果我想要它失败并捕获异常的情况怎么办?我该如何模拟呢?(我并不总是知道要捕获哪个异常,这是使用的主要原因Exception as e)。

  2. 如果我真的通过了这个函数,这是否真的意味着没有捕获到异常并且它通过了每一行?还是因为我设置了 `mock_object.return_value = (True, 'Success!')?

  3. 我只使用了两个依赖项,我是否需要将所有外部依赖项(例如(os、sys、math、datetime))全部修补?或者,如果我的函数正在使用其他函数(已重构)

 def f1(*args, **kwargs):
    f2(..)   # use math, plot, datetime
    f3(..)   # use math and datetime
    f4(..)   # use datetime

    ....

谢谢。对不起,很长的问题。我真的很想擅长编写单元测试。

4

1 回答 1

1

我必须说,在这个特定的用例中,我认为修补/模拟不是最好的选择......

对于这个单元测试,我将在文件系统中创建一个结构,在磁盘中的该结构上运行算法并检查不同的结果(所有这些都没有模拟 os 或 shutil)。

通常我倾向于在外部设置困难或缓慢时(即:可能必须设置一些外部数据库)或它会停止测试(即:打开一些对话框)或当我想做一些困难的事情时使用补丁检查其他情况(例如计算是否实际访问了某些缓存)。

除此之外,修补/模拟太多给我的印象是你的设计有问题(这不是在考虑单元测试的情况下完成的),所以,把它分成更小的块来测试可能会有所帮助......

于 2012-04-27T00:23:45.173 回答