Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为。
python3.3 以前,mock是第三方库,需要安装之后才能使用。python3.3之后,mock作为标准库内置到 unittest。
unittest
unittest是Python标准库中自带的单元测试框架,unittest有时候也被称为PyUnit,就像JUnit是Java语言的标准单元测试框架一样,unittest则是Python语言的标准单元测试框架。
unittest是一个单元测试的框架,能够提供很多测试相关的功能,如:编写测试用例,准备测试环境,生成测试报告等。unittest 中集成了mock,可以用来模拟一些函数返回,未实现的接口等。
unittest导入mock对象:
from unittest import mock
pytest
pytest是基于unittest衍生出来的新的测试框架,使用起来相对于unittest来说更简单、效率来说更高,pytest兼容unittest测试用例,但是反过来unittest不兼容pytest。
pytest也是一个测试框架,公认的比Unittest更加简单和高效。pytest中也有mock方法就是pytest-mock,pytest-mock是一个pytest插件,和 Unittest 中的mock使用接近,大多数方法的定义都是一致的。
- | mock | unittest | pytest |
---|---|---|---|
类型 | 模块 | 框架 | 框架 |
功能 | 模拟对象行为 | 测试相关功能,功能包含mock | 效率更高的框架,功能包含mock |
性能 | 单一模拟功能 | 测试相关多种功能 | 测试相关多种功能,效率更高,更简单 |
mock模块
因为unittest集成了mock,而且python3.0使用更加广泛,所以以unittest中的mock为例介绍mock功能。
mock模块主要的函数如下:
mock.Mock类
Mock对象是模拟的基石,提供了丰富多彩的功能。从测试的阶段来分类包括:
- 构造器:创建mock对象
- 断言方法:判断代码运行的状态
- 管理方法:管理mock对象
- 统计方法:统计mock对象的调用
定义
class unittest.mock.Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs)
Mock是一个类,类中有很多属性和方法,这些属性和方法可以通过参数传递进入,也可以通过实例设置。
重要的参数
return_value
:调用mock的返回值,模拟某一个方法的返回值。side_effect
:调用mock时的返回值,可以是函数,异常类,可迭代对象。使用side_effect可以将模拟对象的返回值变成函数,异常类,可迭代对象等。
当设置了该方法时,如果该方法返回值是DEFAULT,那么返回return_value的值,如果不是,则返回该方法的值。 return_value 和 side_effect 同时存在,side_effect会返回。
如果 side_effect 是异常类或实例时,调用模拟程序时将引发异常。
如果 side_effect 是可迭代对象,则每次调用 mock 都将返回可迭代对象的下一个值。name
:mock 的名称。 这个是用来命名一个mock对象,只是起到标识作用,当你print一个mock对象的时候,可以看到它的name。wraps
: 装饰器:模拟对象要装饰的项目。
如果wrapps不是None,那么调用Mock将把调用传递给wrapped对象(返回实际结果)。
对mock的属性访问将返回一个mock对象,该对象装饰了包装对象的相应属性。spec_set
:更加严格的要求,spec_set=True时,如果访问mock不存在属性或方法会报错spec
: 参数可以把一个对象设置为 Mock 对象的属性。访问mock对象上不存在的属性或方法时,将会抛出属性错误。
示例
main/dao/user.py
# 假设的数据库访问类
class UserDao: