模拟一个在方法调用后更改实例变量的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 
 警告:我从来没有编写过全面的单元测试,而且最近才开始阅读模拟文档,所以尽管我似乎完成了这项工作,但我无法评论它在你的测试方案中的功效.编辑欢迎. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!  | 
                  
