Byt*_*ger 5 python unit-testing mocking
我有一些代码,其中对方法的调用update()会更改某些实例变量的值。我使用更改后的值来留下循环。这是我的代码的简化示例:
def do_stuff(self):
# get a new instance of A
a = get_a()
while True:
a.update()
if a.state == 'state':
break
Run Code Online (Sandbox Code Playgroud)
这是该类的简单版本(我无法更改该类,因为它是第 3 方库):
class A(object):
def __init__(self):
self.state = ''
def update(self):
# call to external system
self.state = extern_func()
Run Code Online (Sandbox Code Playgroud)
现在我想do_stuff()通过模拟 A 类来测试我的函数。为了测试函数的各个方面,我想要拥有 的所有不同值,state并且它应该在每次调用后发生变化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
Run Code Online (Sandbox Code Playgroud)
我可以通过 实现这种行为吗Mock?我知道对于连续的函数调用Mock必须side_effect返回不同的值。但我无法找出在函数调用后更改实例变量值的方法?
设置:
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()
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
side_effectA.update可以是一个函数,您可以使用参数模拟未绑定的方法auto_spec = True。print sep, 'patch update context manager call do_stuff'
def update_mock(self):
self.state = mock()
mock = MagicMock(side_effect = [1,2,3,4, '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
Run Code Online (Sandbox Code Playgroud)
print sep, 'patch update decorator test_do_stuff'
def update_mock(self):
self.state = mock()
mock = MagicMock(side_effect = [1,2,3,4, 'state'])
@patch.object(A, 'update', 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
Run Code Online (Sandbox Code Playgroud)
警告:我从未编写过全面的单元测试,最近才开始阅读模拟文档,因此即使我似乎已经完成了这项工作,我也无法评论它在您的测试方案中的功效。欢迎编辑。
| 归档时间: |
|
| 查看次数: |
7531 次 |
| 最近记录: |