有什么方法可以将模拟方法重置为原始状态? - Python Mock - 模拟1.0b1

时间:2012-07-31 18:13:20

标签: python mocking python-mock

我有以下简化类我在嘲笑:

class myClass(object):
    @staticmethod
    def A():
        #...

    def check(self):
        #code...
        value = self.A()
        #more code...

在我的第一次测试中,我只模拟方法A

from django.test import TestCase
from mock import MagicMock
import myClass

class FirstTest(TestCase):

def setUp(self):
    myClass.A = MagicMock(return_value = 'CPU')

def test(self):
    #some tests 
    myClassObj = myClass()
    myClassObj.check()

在我的第二次测试中,我模拟了整个检查方法:

from django.test import TestCase
from mock import MagicMock
import myClass

class SecondTest(TestCase):

def setUp(self):
    myClass.check = MagicMock(return_value = someObject)

def test(self):
    #some tests 
    myClassObj = myClass()
    myClassObj.check()

现在我的第一次测试中的断言失败了,因为它不是在check()内调用A()和嘲笑check(),而是从我的第二次测试中调用完全模拟的check()

有没有办法在测试后清除并将方法设置为'正常'?我已经尝试了myClass.check.reset_mock(),但它似乎没有做任何事情。移动我的测试顺序也没有做任何事情。

我在http://pypi.python.org/pypi/mock/

使用模拟1.0b1 for python

2 个答案:

答案 0 :(得分:33)

您可以使用mock.patch作为装饰器或上下文管理器:

from mock import patch, MagicMock

@patch('myClass.A', MagicMock(return_value='CPU'))
def test(self):
    pass

或:

def test(self):
    with patch('myClass.A', MagicMock(return_value='CPU')):
        pass

如果您没有向patch提供模拟对象,那么它将提供您可以修改的自动指定的模拟:

@patch('myClass.A')
def test(self, mock_A):
    mock_A.return_value = 'CPU'
    pass

或:

def test(self):
    with patch('myClass.A') as mock_A:
        mock_A.return_value = 'CPU'
        pass

在所有情况下,当装饰测试函数或上下文管理器完成时,将恢复原始值。

答案 1 :(得分:11)

你可以把这个功能藏匿在自己身上,并在你完成后把它放回去。

import unittest

from mock import MagicMock
from MyClass import MyClass

class FirstTest(unittest.TestCase):

    def setUp(self):
        self.A = MyClass.A
        MyClass.A = MagicMock(name='mocked A', return_value='CPU')


    def tearDown(self):
        MyClass.A = self.A

    def test_mocked_static_method(self):
        print 'First Test'
        print MyClass.check
        print MyClass.A


class SecondTest(unittest.TestCase):

    def setUp(self):
        MyClass.check = MagicMock(name='mocked check', return_value=object)

    def test_check_mocked_check_method(self):
        print 'Second Test'
        print MyClass.check
        print MyClass.A


if __name__ == '__main__':
    unittest.main()

运行此文件会提供以下输出:

First Test
<unbound method MyClass.check> 
<MagicMock name='mocked A' id='141382732'>
Second Test
<MagicMock name='mocked check' id='141382860'>
<unbound method MyClass.A>

我发现自己现在使用补丁装饰器比setUp和tearDown更多。在这种情况下你可以做

from mock import patch

@patch('MyClass.A')
def test_mocked_static_method(self, mocked_A)
    mocked_A.return_value = 'CPU'
    # This mock will expire when the test method is finished