在之前的博客中介绍了moco的详细的使用,它主要是基于moco-runner-0.11.0-standalone.jar,通过编写json的文件来实现,那么我们现在来看python之中的mock,那么怎么理解mock了,mock翻译过来就是模拟的意思,也就是说,它是将测试对象所依存的对象替换为虚构对象的库,该虚构对象的调用允许事后查看。在python的2.x版本中,它是属于第三方的库,需要单独的按钮,在python3.3的版本以后,不需要单独的安装,直接导入就可以了,那么我们先看它的安装命令,安装命令为:
pip install mock
见安装的截图:
安装好后,在cmd的命令行中进入到python的环境中,可以直接的导入,见操作的截图:
在python3.3以上的版本中,因为是标准库,就不需要单独的按钮,直接导入就可以了,见操作的截图:
Ok,安装成功后,下来我们来看mock库的经常使用的方法以及它的详细的帮助信息,见获取的代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import mock
print u'查看modk库常用的方法:',dir(mock)
print u'查看mock库详细的帮助信息:',type(help(mock))
mock详细的学习文档可以参考官方的文档,官方地址: http://www.voidspace.org.uk/python/mock/mock.html
下面我们首先来看一个例子,来引入mock,来查看它解决什么问题,以及我们为什么需要mock,知道了这些以后,我们再详细的探讨mock它详细的使用。我们编写如下的一个方法,它要实现的是删除一个C盘下的文件夹,而该文件夹就是Windows文件夹,见该代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import mock
import os
class Remove(object):
def rmdir(self,path='c:/Windows'):
os.rmdir(path)
如果我们要测试rmdir()的方法,那么执行的就是我们每测试一次,就得删除一次文件夹,这样我们的测试结果是通过的,另外有这么几个点需要考虑,第一就是该文件夹是否可删除,如果删除,引起系统出问题如何处理?第二是删除该文件夹的时候,是否已经创建了,难道我们每次删除一次,就得判断是否存在,是否创建,再做删除的操作?很显然这样的一个测试过程,最难的不是第二个问题,而是第一个文件,C盘下的Windows文件夹可以正常的删除吗?可以做删除的操作吗?答案是不可以的,因为我们的系统盘就是C盘下,而Windows文件夹里面储存了很多的系统文件,绝对不允许删除,那么我们如何测试了,这个时候,就需要mock,也就是模拟,我们再写一个方法,模拟rmdir()方法的执行,见更新后的代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import mock
import os
class Remove(object):
def rmdir(self,path='c:/Windows'):
r=os.rmdir(path)
if r==None :
return u'删除成功'
else:
return u'Sorry,删除失败'
def exists_get_rmdir(self):
return self.rmdir()
见测试的代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import mock
import os
import unittest
class Remove(object):
def rmdir(self,path='c:/log'):
r=os.rmdir(path)
if r==None :
return 'success'
else:
return 'fail'
def exists_get_rmdir(self):
return self.rmdir()
class MockTest(unittest.TestCase):
def setUp(self):
self.r=Remove()
def tearDown(self):
pass
def test_success_rmdir(self):
'''
删除目录成功
:return:
'''
success_path=mock.Mock(return_value='success')
self.r.rmdir=success_path
self.assertEqual(self.r.exists_get_rmdir()
,'success')
def test_fail_rmdir(self):
'''
删除目录失败
:return:
'''
fail_path=mock.Mock(return_value='fail')
self.r.rmdir=fail_path
self.assertEqual(self.r.exists_get_rmdir(),
'fail')
if __name__=='__main__':
unittest.main(verbosity=2)
执行如上的代码的时候,我们就不需要考虑是否存在该文件夹,以及该文件夹是否可正常的删除,我们完全使用mock来解决了这个问题,那么我们来看它的执行顺序:
1、找到替换的对象,我们需要测试的是exists_get_imdir()方法,那么我们就需要替换掉rmdir()方法
2、对Mock类进行实例化对象得到mock,并且设置这个mock的行为return_value值,也就是mock虚构对象,在测试通过中,我们虚构return_value为'success',在测试不通过我们虚构return_value为'fail'
3、使用mock对象我们想替换的方法rmdir(),这样我们就替换到了self.r.rmdir
4、编写测试代码,进行断言,我们调用self.r.exists_get_imdir()方法,并且期望它的返回值与我们预期的结果一致(不管是成功的还是失败的)
使用mock虚构对象,比如我们案例使用的Mock(return_value='success'),它是一个什么样的形式了,如果我们使用函数怎么样编写,下来我们详细的来实现这个过程:
见如下模拟类当中的方法,见实现的案例代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import mock
mock=mock.Mock()
mock.info.return_value='Hello Mock'
print mock.info()
class F:
def info(self):
return 'Hello Mock'
f=F()
print f.info()