我有以下简化类我在嘲笑:
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()
,但它似乎没有做任何事情。移动我的测试顺序也没有做任何事情。
答案 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