2012-04-23 164 views
4

假设我要断言result是在一个特定的格式,我可以把返回值的东西作为(True, 'Success')Dillemma使用模拟对象

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.existsTrue作为返回值。但在一个单元测试中,我想跳过这个,我该如何补丁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 

    .... 

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

回答

1

我必须说,在这个特殊的用例,我不认为打补丁/嘲讽将是最好的选择...

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

通常我倾向于在外部设置困难或缓慢时(即:可能需要设置一些外部数据库),或者当它暂停测试(即:打开某个对话框)或者当我想要做一些难以检查的事情(比如计数是否实际访问了某个缓存)。

除此之外,修补/嘲弄太多会让我觉得你的设计有问题(这不是在单元测试的基础上完成的),所以把它分成小块进行测试可能会有帮助...