模拟一个在方法调用后更改实例变量的python类?
发布时间:2020-12-20 13:44:50 所属栏目:Python 来源:网络整理
导读:我有一些代码,其中对方法update()的调用会更改某些实例变量的值.我使用更改的值来保留循环.这是我的代码的简化示例: def do_stuff(self): # get a new instance of A a = get_a() while True: a.update() if a.state == 'state': break 这个类的简单版本(我
|
我有一些代码,其中对方法update()的调用会更改某些实例变量的值.我使用更改的值来保留循环.这是我的代码的简化示例:
def do_stuff(self):
# get a new instance of A
a = get_a()
while True:
a.update()
if a.state == 'state':
break
这个类的简单版本(我无法更改类,因为它是第三方库): class A(object):
def __init__(self):
self.state = ''
def update(self):
# call to external system
self.state = extern_func()
现在我想通过模拟类A来测试我的函数do_stuff().为了测试函数的每个方面,我想拥有所有不同的状态值,并且它应该在每次调用a.update()之后改变(迭代不同的状态). 我开始使用这个设置进行单元测试: from mock import Mock,patch
import unittest
class TestClass(unittest.TestClass):
@patch('get_a')
def test_do_stuff(self,mock_get_a):
mock_a = Mock(spec=A)
mock_get_a.return_value = mock_a
# do some assertions
我能用Mock实现这种行为吗? 解决方法
建立:
from mock import Mock,MagicMock,patch
sep = '***********************n'
# non-mock mocks
def get_a():
return A()
def extern_func():
return 'foo'
def do_stuff(self):
# get a new instance of A
a = get_a()
while True:
a.update()
print a.state
if a.state == 'state':
break
class A(object):
def __init__(self):
self.state = ''
def update(self):
# call to external system
self.state = extern_func()
正如@Simeon Viser所提到的,模拟extern_func会起作用: print sep,'patch extern'
mock = MagicMock(side_effect = [1,2,3,4,'state'])
@patch('__main__.extern_func',mock)
def foo():
do_stuff(3)
foo()
>>>
***********************
patch extern
1
2
3
4
state
side_effect可以是一个函数,您可以使用auto_spec = True参数模拟未绑定的方法A.update. 使用上下文管理器: print sep,'patch update context manager call do_stuff'
def update_mock(self):
self.state = mock()
mock = MagicMock(side_effect = [1,'state'])
with patch.object(A,'update',autospec = True) as mock_update:
mock_update.side_effect = update_mock
do_stuff(3)
>>>
***********************
patch update context manager call do_stuff
1
2
3
4
state
使用装饰者: print sep,'patch update decorator test_do_stuff'
def update_mock(self):
self.state = mock()
mock = MagicMock(side_effect = [1,'state'])
@patch.object(A,autospec = True,side_effect = update_mock)
def test_do_stuff(self):
do_stuff(3)
test_do_stuff()
>>>
***********************
patch update decorator test_do_stuff
1
2
3
4
state
警告:我从来没有编写过全面的单元测试,而且最近才开始阅读模拟文档,所以尽管我似乎完成了这项工作,但我无法评论它在你的测试方案中的功效.编辑欢迎. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
