-
Notifications
You must be signed in to change notification settings - Fork 0
Python unittest
关于单元测试,这边提供几个主要用到对方法进行Mock的使用样例:
独立的方法,指的是不属于某个class,而是独立存放于某个python的模块文件里面。
独立方法的mock,可以通过mock.patch的with语句来完成,举例如下:
为hackathon.user.login里面的GithubLogin().login()方法写单元测试
这种情况下,就需要对里面的get_remote方法进行mock
而这个get_remote不属于任何class,只是存放于functions这个python模块里面
with mock.patch('hackathon.user.login.get_remote') as get_remote_method:
……
……
get_remote_method.return_value = '''{"nickname":"test_nickname","figureurl":"test_figureurl"}'''
……其中,注意 'hackathon.user.login.get_remote':
这里指定的是get_remote方法使用的“目的地”进行描述,而不是对方法的“来源”进行描述
即:在hackathon.user.login这个模块里面使用get_remote的时候,把它mock掉,并且另转成get_remote_method
#Mock一个对象里面的方法
主要通过mock.patch.object()注解的方式来做(实际上也可以用with语句,参考上个例子的格式)
举例:
@patch.object(AdminManager, 'validate_admin_hackathon_request', return_value=True)
def test_check_admin_hackathon_authority_success(self, mock_thethod):
……
……
self.assertTrue(admin_manager.check_admin_hackathon_authority())
……这个例子里面,在admin_manager.check_admin_hackathon_authority()方法里面回去调用validate_admin_hackathon_request()方法,而这个方法就是处于AdminManager的class里面
#同一函数多次调用
在某些情况下,我门在某个函数里面会多次调用另一个函数,如:
在login的时候,就要多次调用get_remote去与第三方Oauth进行交互,而且每次返回值是不一样的。
这个时候,就需要用到side_effect来mock每次调用的返回结果了:
举例如下:
with mock.patch('hackathon.user.login.get_remote') as get_remote_method:
……
info = '''1234567890{"openid":"test_openid","client_id":"test_client_id"}1234'''
email_info_resp = '''{"nickname":"test_nickname","figureurl":"test_figureurl"}'''
get_remote_method.side_effect = [info, email_info_resp]
……side_effect 实际就是该函数return_value的列表集合形式 这里面side_effect赋值成一个包含两个对象的List,即调用get_remote_method两次 第一次取list里面第一个值,第二次取第二个,以此类推~
#让函数抛出异常 在为catch分支写单元测试的时候,需要mock某个函数并且让它抛出异常: 这个可以像return_value那样,直接赋值某个Exception
mock_methon.side_effect = Exception#Mock一个对象的属性
在某些时候,我们不仅需要mock某个对象的方法,有可能还需要mock该对象的某个属性
这个时候,就需要对对象的属性进行mock。
举例,在register_mgr的deal_with_user_and_register_when_login方法里面有个lambda表达式
emails = map(lambda x: x.email, user.emails)
user是作为参数传进来,而这个时候,就需要对user的emails这个属性进行mock,具体实现方法如下:
user_email = UserEmail(id=1, email='test@test.com', user_id=1)
user = mock.MagicMock(id=1, emails=[user_email])
因为lambda表达式要求user.emails必须是一个集合
而mock是不支持集合,因此更换成mock.Magick()